@@ -80,17 +80,22 @@ def get_random_content(node_name):
8080 }
8181 }
8282
83- def log_error (error , node_name , step = 'unknown' , remote_node = None ):
84- print (f"\n ❌ Error on { node_name } during { step } " )
85- print (f"🔺 Type: { type (error ).__name__ } " )
86- print (f"🧵 Message: { str (error )} " )
87- tb = traceback .extract_tb (sys .exc_info ()[2 ])
88- user_tb = [entry for entry in tb if "site-packages" not in entry .filename ]
89- if user_tb :
90- last = user_tb [- 1 ]
91- print (f"📍 Location: { last .filename } , line { last .lineno } , in { last .name } " )
92-
93- # Create a cleaner error message for grouping
83+ def log_error (error , node_name , step = 'unknown' , remote_node = None , ka_number = None , attempt_number = None ):
84+ attempt_key = f"KA #{ ka_number } - attempt { attempt_number } " if ka_number and attempt_number else f"KA #{ ka_number } "
85+ if node_name not in error_stats :
86+ error_stats [node_name ] = {}
87+ if attempt_key not in error_stats [node_name ]:
88+ error_stats [node_name ][attempt_key ] = {
89+ "ka_label" : f"KA #{ ka_number } " if ka_number else "Unknown KA" ,
90+ "attempt" : attempt_number ,
91+ "publish_error" : None ,
92+ "query_error" : None ,
93+ "publisher_get_error" : None ,
94+ "non_publisher_get_error" : None ,
95+ "time_stamp" : datetime .utcnow ().isoformat ()
96+ }
97+ # derive error_message (same as before)...
98+ error_message = str (error )
9499 if isinstance (error , TimeoutError ) or isinstance (error , concurrent .futures .TimeoutError ):
95100 error_message = f"Timeout after 3 minutes during { step } "
96101 else :
@@ -103,35 +108,23 @@ def log_error(error, node_name, step='unknown', remote_node=None):
103108 error_message = str (error )
104109 except Exception :
105110 error_message = str (error )
106-
107111 error_message = error_message .splitlines ()[0 ][:100 ]
108-
109- # Create a generic key that groups similar errors
110- if remote_node :
111- key = f"{ step } — { type (error ).__name__ } : { error_message } on { remote_node } "
112- else :
113- key = f"{ step } — { type (error ).__name__ } : { error_message } "
114-
115- # Store errors in the global error_stats for this node
116- if node_name not in error_stats :
117- error_stats [node_name ] = {}
118-
119- if key in error_stats [node_name ]:
120- error_stats [node_name ][key ] += 1
121- else :
122- error_stats [node_name ][key ] = 1
123-
124- # Write to individual node error file (parallel-safe)
112+ if step == "publishing" :
113+ error_stats [node_name ][attempt_key ]["publish_error" ] = error_message
114+ elif step == "querying" :
115+ error_stats [node_name ][attempt_key ]["query_error" ] = error_message
116+ elif step == "local get" :
117+ error_stats [node_name ][attempt_key ]["publisher_get_error" ] = error_message
118+ elif step == "get" :
119+ error_stats [node_name ][attempt_key ]["non_publisher_get_error" ] = error_message
120+ if not error_stats [node_name ][attempt_key ]["time_stamp" ]:
121+ error_stats [node_name ][attempt_key ]["time_stamp" ] = datetime .utcnow ().isoformat ()
125122 node_error_file = f"test_output/errors_{ node_name .replace (' ' , '_' )} .json"
126123 os .makedirs ("test_output" , exist_ok = True )
127-
128- # Use the in-memory error_stats as the source of truth for this node
129- # This ensures we only track errors from the current test run
130124 node_errors = error_stats .get (node_name , {}).copy ()
131-
132- # Save current state to individual node file
125+ error_data = {"blockchain_name" : BLOCKCHAIN , "node_name" : node_name , "errors" : node_errors }
133126 with open (node_error_file , 'w' ) as f :
134- json .dump (node_errors , f , indent = 2 )
127+ json .dump (error_data , f , indent = 2 )
135128
136129def safe_rate (success , fail ):
137130 total = success + fail
@@ -179,7 +172,7 @@ def run_test_for_node(node, index):
179172 publish_success += 1
180173 publish_times .append (end - start )
181174 except Exception as e :
182- log_error (e , name , "publishing" )
175+ log_error (e , name , "publishing" , ka_number = i + 1 , attempt_number = i + 1 )
183176 ual = "did:dkg:base:84532/0xd5550173b0f7b8766ab2770e4ba86caf714a5af5/195774"
184177 print (f"⚠️ Using fallback UAL: { ual } " )
185178 failed_assets .append (f"KA #{ i + 1 } (Publish failed — No UAL)" )
@@ -201,7 +194,7 @@ def run_test_for_node(node, index):
201194 query_success += 1
202195 query_times .append (end - start )
203196 except Exception as e :
204- log_error (e , name , "querying" )
197+ log_error (e , name , "querying" , ka_number = i + 1 , attempt_number = i + 1 )
205198 query_fail += 1
206199 failed_assets .append (f"KA #{ i + 1 } (Query failed — UAL: { ual } )" )
207200
@@ -214,7 +207,7 @@ def run_test_for_node(node, index):
214207 local_get_success += 1
215208 local_get_times .append (end - start )
216209 except Exception as e :
217- log_error (e , name , "local get" )
210+ log_error (e , name , "local get" , ka_number = i + 1 , attempt_number = i + 1 )
218211 local_get_fail += 1
219212 failed_assets .append (f"KA #{ i + 1 } (Local Get failed — UAL: { ual } )" )
220213
@@ -245,7 +238,7 @@ def run_test_for_node(node, index):
245238 remote_get_success += 1
246239 remote_get_times .append (end - start )
247240 except Exception as e :
248- log_error (e , name , "get" , remote_name )
241+ log_error (e , name , "get" , remote_name , ka_number = i + 1 , attempt_number = i + 1 )
249242 remote_get_fail += 1
250243 failed_assets .append (f"KA #{ i + 1 } (Get failed — UAL: { ual } )" )
251244
0 commit comments