Python requests库能否从RetryError中获取原始HTTP响应?
解决方案
有两种常用实现方式可以拿到原始响应:
方案1:最小改动,复用原有错误处理逻辑
在定义重试策略时添加raise_on_status=False配置即可,该配置会让重试逻辑在耗尽次数后不再直接抛出MaxRetryError,而是返回最后一次请求的响应,你的原有错误处理逻辑无需任何调整:
from urllib3.util.retry import Retry RETRY_STRATEGY = Retry( total=3, # 替换为你的原有重试次数 backoff_factor=1, # 替换为你的原有退避配置 status_forcelist=[500, 502, 503, 504], # 替换为你的原有重试触发状态码 raise_on_status=False # 新增配置 )
拿到请求返回的响应后,还是按照你之前的逻辑调用response.raise_for_status()即可,抛出的异常会正常携带response属性。
方案2:自定义重试类,保留重试耗尽的异常特征
如果你需要明确区分「重试耗尽异常」和「单次请求异常」,可以自定义Retry子类将最后一次响应绑定到异常上:
步骤1:实现自定义重试类
from urllib3.util.retry import Retry from urllib3.exceptions import MaxRetryError class RetryWithResponse(Retry): def increment(self, *args, **kwargs): current_resp = kwargs.get("response") try: return super().increment(*args, **kwargs) except MaxRetryError as e: # 将最后一次响应绑定到异常对象上 e.last_response = current_resp raise
步骤2:替换原有重试策略的类
将你原有RETRY_STRATEGY实例化时的Retry类替换为上面实现的RetryWithResponse即可。
步骤3:调整顶层错误处理逻辑
import requests from urllib3.exceptions import MaxRetryError as Urllib3MaxRetryError if isinstance(error, requests.RequestException): req = error.request resp = None # 原有普通异常场景 if error.response is not None: resp = error.response # 重试耗尽异常场景 elif ( error.__context__ is not None and isinstance(error.__context__, Urllib3MaxRetryError) and hasattr(error.__context__, "last_response") ): resp = error.__context__.last_response if resp is not None: # 原有日志记录逻辑保持不变 # Log request and response ...
内容的提问来源于stack exchange,提问作者Hubro
相关产品推荐
相关产品推荐

