@@ -102,44 +102,60 @@ def _retry_request(self, func, *args, retry_on_status_codes=[500, 502, 503, 504]
102102 """
103103 max_retries = max_retries_override if max_retries_override is not None else self .config ['retry' ]['max_retries' ]
104104 retry_delay = self .config ['retry' ]['retry_delay' ]
105+ actual_retry_count = 0 # 实际重试次数(不包括400错误的尝试)
105106
106- for attempt in range (max_retries ):
107+ attempt = 0
108+ while attempt < max_retries :
107109 try :
108110 result = func (* args , ** kwargs )
109- return result , attempt # 成功,返回结果和重试次数
111+ return result , actual_retry_count # 成功,返回结果和实际重试次数
110112 except requests .exceptions .Timeout as e :
113+ actual_retry_count += 1
111114 if attempt < max_retries - 1 :
112- print (f" ⚠ 请求超时,{ retry_delay } 秒后重试 ({ attempt + 1 } /{ max_retries } )" )
115+ print (f" ⚠ 请求超时,{ retry_delay } 秒后重试 ({ actual_retry_count } /{ max_retries } )" )
113116 time .sleep (retry_delay )
117+ attempt += 1
114118 continue
115119 else :
116120 raise # 最后一次重试失败,抛出异常
117121 except requests .exceptions .ConnectionError as e :
122+ actual_retry_count += 1
118123 if attempt < max_retries - 1 :
119- print (f" ⚠ 连接错误,{ retry_delay } 秒后重试 ({ attempt + 1 } /{ max_retries } )" )
124+ print (f" ⚠ 连接错误,{ retry_delay } 秒后重试 ({ actual_retry_count } /{ max_retries } )" )
120125 time .sleep (retry_delay )
126+ attempt += 1
121127 continue
122128 else :
123129 raise
124130 except requests .exceptions .HTTPError as e :
131+ # 400 业务错误不重试,直接抛出,并且不计入重试次数
132+ if hasattr (e , 'response' ) and e .response .status_code == 400 :
133+ print (f" ℹ HTTP 400 业务错误,不进行重试且不计入重试次数" )
134+ raise
125135 # 检查是否是可重试的状态码
126136 if hasattr (e , 'response' ) and e .response .status_code in retry_on_status_codes :
137+ actual_retry_count += 1
127138 if attempt < max_retries - 1 :
128- print (f" ⚠ HTTP { e .response .status_code } 错误,{ retry_delay } 秒后重试 ({ attempt + 1 } /{ max_retries } )" )
139+ print (f" ⚠ HTTP { e .response .status_code } 错误,{ retry_delay } 秒后重试 ({ actual_retry_count } /{ max_retries } )" )
129140 time .sleep (retry_delay )
141+ attempt += 1
130142 continue
131143 raise # 不可重试的HTTP错误或最后一次重试失败
132144 except Exception as e :
133145 # 所有其他异常也进行重试
146+ actual_retry_count += 1
134147 if attempt < max_retries - 1 :
135- print (f" ⚠ 发生错误 ({ e .__class__ .__name__ } : { str (e )} ),{ retry_delay } 秒后重试 ({ attempt + 1 } /{ max_retries } )" )
148+ print (f" ⚠ 发生错误 ({ e .__class__ .__name__ } : { str (e )} ),{ retry_delay } 秒后重试 ({ actual_retry_count } /{ max_retries } )" )
136149 time .sleep (retry_delay )
150+ attempt += 1
137151 continue
138152 else :
139153 raise # 最后一次重试失败,抛出异常
140154
155+ attempt += 1
156+
141157 # 理论上不应该到这里
142- return None , max_retries
158+ return None , actual_retry_count
143159
144160 def _safe_json_parse (self , response , context : str = "" ):
145161 """
@@ -403,6 +419,30 @@ def make_request():
403419 if retry_count > 0 :
404420 print (f" ℹ 经过 { retry_count } 次HTTP重试后成功" )
405421
422+ # 检查是否为 HTTP 400 错误,如果是则不进行业务重试
423+ if response .status_code == 400 :
424+ print (f" ℹ HTTP 400 业务错误,跳过业务重试" )
425+ # 尝试解析响应以获取错误信息
426+ rq_json , json_error = self ._safe_json_parse (response , "密钥注册" )
427+ error_msg = rq_json .get ('message' , rq_json .get ('msg' , '未知错误' )) if rq_json else '无法解析错误信息'
428+ error_code = rq_json .get ('code' , 'N/A' ) if rq_json else 'N/A'
429+
430+ self .key_registration_status = "failed"
431+ print (f"✗ 密钥注册失败 [HTTP 400, code: { error_code } ]: { error_msg } " )
432+ error_info = {
433+ "type" : "BusinessError" ,
434+ "message" : f"{ error_msg } (HTTP 400 不重试)" ,
435+ "http_status" : 400 ,
436+ "error_code" : error_code ,
437+ "response_body" : rq_json if rq_json else json_error .get ('response_text' , '' ),
438+ "url" : url ,
439+ "duration" : duration ,
440+ "retry_count" : total_retry_count ,
441+ "severity" : "ERROR"
442+ }
443+ self ._send_feishu_notification (self ._format_error_notification (check_name , error_info ))
444+ return False
445+
406446 # 使用安全JSON解析
407447 rq_json , json_error = self ._safe_json_parse (response , "密钥注册" )
408448
@@ -585,6 +625,31 @@ def make_request():
585625 if retry_count > 0 :
586626 print (f" ℹ 经过 { retry_count } 次HTTP重试后成功" )
587627
628+ # 检查是否为 HTTP 400 错误,如果是则不进行业务重试
629+ if response .status_code == 400 :
630+ print (f" ℹ HTTP 400 业务错误,跳过业务重试" )
631+ # 尝试解析响应以获取错误信息
632+ rq_json , json_error = self ._safe_json_parse (response , "签名校验" )
633+ error_msg = rq_json .get ('message' , rq_json .get ('msg' , '未知错误' )) if rq_json else '无法解析错误信息'
634+ error_code = rq_json .get ('code' , 'N/A' ) if rq_json else 'N/A'
635+
636+ if logger :
637+ logger .info ("校验失败" )
638+ print (f"✗ 签名校验失败 [HTTP 400, code: { error_code } ]: { error_msg } " )
639+ error_info = {
640+ "type" : "BusinessError" ,
641+ "message" : f"{ error_msg } (HTTP 400 不重试)" ,
642+ "http_status" : 400 ,
643+ "error_code" : error_code ,
644+ "response_body" : rq_json if rq_json else json_error .get ('response_text' , '' ),
645+ "url" : url ,
646+ "duration" : duration ,
647+ "retry_count" : total_retry_count ,
648+ "severity" : "ERROR"
649+ }
650+ self ._send_feishu_notification (self ._format_error_notification (check_name , error_info ))
651+ return False
652+
588653 # 使用安全JSON解析
589654 rq_json , json_error = self ._safe_json_parse (response , "签名校验" )
590655
@@ -775,6 +840,29 @@ def make_request():
775840 if retry_count > 0 :
776841 print (f" ℹ 经过 { retry_count } 次HTTP重试后成功" )
777842
843+ # 检查是否为 HTTP 400 错误,如果是则不进行业务重试
844+ if response .status_code == 400 :
845+ print (f" ℹ HTTP 400 业务错误,跳过业务重试" )
846+ # 尝试解析响应以获取错误信息
847+ resp_json , json_error = self ._safe_json_parse (response , "设备Token认证" )
848+ error_msg = resp_json .get ('message' , resp_json .get ('msg' , '未知错误' )) if resp_json else '无法解析错误信息'
849+ error_code = resp_json .get ('code' , 'N/A' ) if resp_json else 'N/A'
850+
851+ if logger :
852+ logger .error (f"设备Token认证失败: { error_msg } " )
853+ print (f"✗ 设备Token认证失败 [HTTP 400, code: { error_code } ]: { error_msg } " )
854+ error_detail = self ._build_error_detail (
855+ url = url ,
856+ error_type = "BusinessError" ,
857+ error_message = f"{ error_msg } (HTTP 400 不重试)" ,
858+ http_status = 400 ,
859+ error_code = error_code ,
860+ response_body = resp_json if resp_json else json_error .get ('response_text' , '' ),
861+ retry_count = total_retry_count ,
862+ duration = duration
863+ )
864+ return False , error_detail
865+
778866 # 使用安全JSON解析
779867 resp_json , json_error = self ._safe_json_parse (response , "设备Token认证" )
780868
0 commit comments