@@ -76,16 +76,20 @@ def get_random_content(node_name):
7676 }
7777
7878def log_error (error , node_name , step = 'unknown' , remote_node = None , ka_number = None , attempt_number = None ):
79- print (f"\n ❌ Error on { node_name } during { step } " )
80- print (f"🔺 Type: { type (error ).__name__ } " )
81- print (f"🧵 Message: { str (error )} " )
82- tb = traceback .extract_tb (sys .exc_info ()[2 ])
83- user_tb = [entry for entry in tb if "site-packages" not in entry .filename ]
84- if user_tb :
85- last = user_tb [- 1 ]
86- print (f"📍 Location: { last .filename } , line { last .lineno } , in { last .name } " )
87-
88- # Create a cleaner error message for grouping
79+ attempt_key = f"KA #{ ka_number } - attempt { attempt_number } " if ka_number and attempt_number else f"KA #{ ka_number } "
80+ if node_name not in error_stats :
81+ error_stats [node_name ] = {}
82+ if attempt_key not in error_stats [node_name ]:
83+ error_stats [node_name ][attempt_key ] = {
84+ "ka_label" : f"KA #{ ka_number } " if ka_number else "Unknown KA" ,
85+ "attempt" : attempt_number ,
86+ "publish_error" : None ,
87+ "query_error" : None ,
88+ "publisher_get_error" : None ,
89+ "non_publisher_get_error" : None ,
90+ "time_stamp" : datetime .utcnow ().isoformat ()
91+ }
92+ error_message = str (error )
8993 if isinstance (error , TimeoutError ) or isinstance (error , concurrent .futures .TimeoutError ):
9094 error_message = f"Timeout after 3 minutes during { step } "
9195 else :
@@ -98,35 +102,27 @@ def log_error(error, node_name, step='unknown', remote_node=None, ka_number=None
98102 error_message = str (error )
99103 except Exception :
100104 error_message = str (error )
101-
102105 error_message = error_message .splitlines ()[0 ][:100 ]
103-
104- # Create a generic key that groups similar errors
105- if remote_node :
106- key = f"{ step } — { type (error ).__name__ } : { error_message } on { remote_node } "
107- else :
108- key = f"{ step } — { type (error ).__name__ } : { error_message } "
109-
110- # Store errors in the global error_stats for this node
111- if node_name not in error_stats :
112- error_stats [node_name ] = {}
113-
114- if key in error_stats [node_name ]:
115- error_stats [node_name ][key ] += 1
116- else :
117- error_stats [node_name ][key ] = 1
118-
119- # Write to individual node error file (parallel-safe)
106+ if step == "publishing" :
107+ error_stats [node_name ][attempt_key ]["publish_error" ] = error_message
108+ elif step == "querying" :
109+ error_stats [node_name ][attempt_key ]["query_error" ] = error_message
110+ elif step == "local get" :
111+ error_stats [node_name ][attempt_key ]["publisher_get_error" ] = error_message
112+ elif step == "get" :
113+ error_stats [node_name ][attempt_key ]["non_publisher_get_error" ] = error_message
114+ if not error_stats [node_name ][attempt_key ]["time_stamp" ]:
115+ error_stats [node_name ][attempt_key ]["time_stamp" ] = datetime .utcnow ().isoformat ()
120116 node_error_file = f"test_output/errors_{ node_name .replace (' ' , '_' )} .json"
121117 os .makedirs ("test_output" , exist_ok = True )
122-
123- # Use the in-memory error_stats as the source of truth for this node
124- # This ensures we only track errors from the current test run
125118 node_errors = error_stats .get (node_name , {}).copy ()
126-
127- # Save current state to individual node file
119+ error_data = {
120+ "blockchain_name" : BLOCKCHAIN ,
121+ "node_name" : node_name ,
122+ "errors" : node_errors
123+ }
128124 with open (node_error_file , 'w' ) as f :
129- json .dump (node_errors , f , indent = 2 )
125+ json .dump (error_data , f , indent = 2 )
130126
131127def safe_rate (success , fail ):
132128 total = success + fail
@@ -174,7 +170,7 @@ def run_test_for_node(node, index):
174170 publish_success += 1
175171 publish_times .append (end - start )
176172 except Exception as e :
177- log_error (e , name , "publishing" , ka_number = i + 1 , attempt_number = 1 )
173+ log_error (e , name , "publishing" , ka_number = i + 1 , attempt_number = i + 1 )
178174 ual = "did:dkg:otp:2043/0x8f678eb0e57ee8a109b295710e23076fa3a443fe/3598384"
179175 print (f"⚠️ Using fallback UAL: { ual } " )
180176 failed_assets .append (f"KA #{ i + 1 } (Publish failed — No UAL)" )
@@ -196,7 +192,7 @@ def run_test_for_node(node, index):
196192 query_success += 1
197193 query_times .append (end - start )
198194 except Exception as e :
199- log_error (e , name , "querying" , ka_number = i + 1 , attempt_number = 1 )
195+ log_error (e , name , "querying" , ka_number = i + 1 , attempt_number = i + 1 )
200196 query_fail += 1
201197 failed_assets .append (f"KA #{ i + 1 } (Query failed — UAL: { ual } )" )
202198
@@ -209,7 +205,7 @@ def run_test_for_node(node, index):
209205 local_get_success += 1
210206 local_get_times .append (end - start )
211207 except Exception as e :
212- log_error (e , name , "local get" , ka_number = i + 1 , attempt_number = 1 )
208+ log_error (e , name , "local get" , ka_number = i + 1 , attempt_number = i + 1 )
213209 local_get_fail += 1
214210 failed_assets .append (f"KA #{ i + 1 } (Local Get failed — UAL: { ual } )" )
215211
@@ -240,7 +236,7 @@ def run_test_for_node(node, index):
240236 remote_get_success += 1
241237 remote_get_times .append (end - start )
242238 except Exception as e :
243- log_error (e , name , "get" , remote_name , ka_number = i + 1 , attempt_number = 1 )
239+ log_error (e , name , "get" , remote_name , ka_number = i + 1 , attempt_number = i + 1 )
244240 remote_get_fail += 1
245241 failed_assets .append (f"KA #{ i + 1 } (Get failed — UAL: { ual } )" )
246242
0 commit comments