You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 18:45:03