gpt4 book ai didi

python - 捕获requests.exceptions.RetryError时如何获取底层失败的请求数据?

转载 作者:行者123 更新时间:2023-12-05 05:35:55 31 4
gpt4 key购买 nike

我使用某种标准模式在 Python 中围绕 requests 请求放置重试行为,

import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

retry_strategy = Retry(
total=HTTP_RETRY_LIMIT,
status_forcelist=HTTP_RETRY_CODES,
method_whitelist=HTTP_RETRY_METHODS,
backoff_factor=HTTP_BACKOFF_FACTOR
)
adapter = HTTPAdapter(max_retries=retry_strategy)
http = requests.Session()
http.mount("https://", adapter)
http.mount("http://", adapter)

...

try:
response = http.get(... some request params ...)
except requests.Exceptions.RetryError as err:
# Do logic with err to perform error handling & logging.

不幸的是the docs on RetryError什么都不解释,当我如上所述拦截异常对象时,err.responseNone。虽然您可以调用 str(err) 来获取异常的消息字符串,但这将需要不合理的字符串解析来尝试恢复特定的响应细节,即使有人愿意尝试,消息实际上省略了必要的细节。例如,来自网站上故意调用的一个这样的响应给出了 400 秒(并不是说你真的会重试这个,而是为了调试)给出了一条消息 “(由 ResponseError('太多 400 错误响应')引起)" - 它省略了实际的响应细节,比如所请求站点自己对 400 错误性质的描述文本(这可能对确定处理至关重要,甚至只是为了记录错误而传回)。

我想做的是接收上次不成功的重试尝试的响应,并使用该特定失败的状态代码和描述来确定处理逻辑。尽管我想让它在重试后变得健壮,但在最终处理错误时,我仍然需要知道除了“重试太多”之外的潜在故障。

是否可以从为重试引发的异常中提取此信息?

最佳答案

我们无法在每个异常中都得到响应,因为请求可能尚未发送,或者请求或响应可能尚未到达其目的地。例如,这些异常不会得到响应。

urllib3.exceptions.ConnectTimeoutError
urllib3.exceptions.SSLError
urllib3.exceptions.NewConnectionError

urllib3.util.Retry 中有一个名为 raise_on_status 的参数,默认为 True。如果它被设置为 Falseurllib3.exceptions.MaxRetryError 将不会被raised。如果没有异常 raised,则可以肯定响应已经到达。现在可以很容易地在 try block 的 else block 中 response.raise_for_status 包裹在另一个 try 中。

我已将 except RetryError 更改为 except Exception 以捕获其他异常。

import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
from requests.exceptions import RetryError

# DEFAULT_ALLOWED_METHODS = frozenset({'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PUT', 'TRACE'})
# Default methods to be used for allowed_methods
# RETRY_AFTER_STATUS_CODES = frozenset({413, 429, 503})
# Default status codes to be used for status_forcelist

HTTP_RETRY_LIMIT = 3
HTTP_BACKOFF_FACTOR = 0.2

retry_strategy = Retry(
total=HTTP_RETRY_LIMIT,
backoff_factor=HTTP_BACKOFF_FACTOR,
raise_on_status=False,
)
adapter = HTTPAdapter(max_retries=retry_strategy)
http = requests.Session()
http.mount("https://", adapter)
http.mount("http://", adapter)
try:
response = http.get("https://httpbin.org/status/503")
except Exception as err:
print(err)
else:
try:
response.raise_for_status()
except Exception as e:
# Do logic with err to perform error handling & logging.
print(response.reason)
# Or
# print(e.response.reason)
else:
print(response.text)

测试;

# https://httpbin.org/user-agent
➜ python requests_retry.py
{
"user-agent": "python-requests/2.28.1"
}

# url = https://httpbin.org/status/503
➜ python requests_retry.py
SERVICE UNAVAILABLE

关于python - 捕获requests.exceptions.RetryError时如何获取底层失败的请求数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73394472/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com