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

Python requests如何对status_code=200但error非零的响应触发重试

解决方案

方案1:自定义继承urllib3的Retry类(推荐,可复用urllib3原生重试逻辑)

urllib3的Retry类支持重写响应可重试判断逻辑,你可以继承该类重写is_response_retryable方法,在方法内解析响应体的error字段判断是否需要重试,示例代码如下:

import json
from urllib3 import Retry

class CustomRetry(Retry):
    def is_response_retryable(self, response):
        # 可保留原生状态码判断逻辑,不需要也可以删除
        if super().is_response_retryable(response):
            return True
        # 解析响应体判断error字段
        try:
            data = json.loads(response.data)
            return data.get("error", 0) != 0
        except (json.JSONDecodeError, AttributeError):
            # 响应不是合法JSON的场景可按需设置是否重试
            return True

之后将自定义的CustomRetry实例传给urllib3的PoolManager即可,其余重试参数(重试次数、间隔、允许重试的方法白名单等)和原生Retry的用法完全一致。

方案2:外层封装独立重试逻辑

如果不想修改urllib3的内置重试逻辑,也可以在请求外层自行封装重试判断,适配性更高,可灵活控制重试触发条件、间隔、回调逻辑等,以下是用通用重试库tenacity实现的示例:

import json
import urllib3
from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_result

http = urllib3.PoolManager()

def is_api_failed(response):
    """判断接口是否返回失败需要重试"""
    try:
        data = json.loads(response.data)
        return data.get("error", 0) != 0
    except Exception:
        return True

# 重试配置:最多重试3次,指数退避间隔,接口返回失败则触发重试
@retry(
    stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=1, min=1, max=10),
    retry=retry_if_result(is_api_failed)
)
def send_request(method, url, **kwargs):
    resp = http.request(method, url, **kwargs)
    return resp

注意事项

  • 解析响应体前建议先判断响应的Content-Type是否为JSON,避免不必要的解码错误
  • 非幂等请求(比如POST提交数据)的重试要谨慎,避免重复提交导致业务异常,可以限制仅GET、HEAD等幂等方法重试
  • 如果响应体较大,多次读取可能产生性能损耗,可以按需添加仅小体积响应才解析body判断的逻辑

内容的提问来源于stack exchange,提问作者caverac

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 03:06:02