ely*_*ely 5 python exception python-3.x python-requests retry-logic
requests
我正在使用一种有点标准的模式来在 Python 中的请求周围放置重试行为,
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.
Run Code Online (Sandbox Code Playgroud)
不幸的是,RetryError 上的文档没有解释任何内容,当我如上所述拦截异常对象时,err.response
是None
. 虽然您可以调用str(err)
来获取异常的消息字符串,但这将需要不合理的字符串解析来尝试恢复特定的响应详细信息,即使有人愿意尝试,该消息实际上也会忽略必要的详细信息。例如,来自某个站点上的故意调用的一个此类响应给出了 400 秒(并不是说您真的会重试此操作,而只是为了调试),它会给出一条消息 -"(Caused by ResponseError('too many 400 error responses'))"
它忽略了实际的响应详细信息,例如请求站点自己的描述文本400 错误的性质(这对于确定处理至关重要,甚至只是回传以记录错误)。
我想要做的是接收response
最后一次不成功的重试尝试,并使用该特定失败的状态代码和描述来确定处理逻辑。尽管我想让它在重试后变得健壮,但在最终处理错误时,我仍然需要知道“重试次数过多”之外的潜在故障。
是否可以从重试引发的异常中提取此信息?
我们无法在每个异常中获得响应,因为请求可能尚未发送,或者请求或响应可能尚未到达其目的地。\n例如,这些异常不会获得响应。
\nurllib3.exceptions.ConnectTimeoutError\nurllib3.exceptions.SSLError\nurllib3.exceptions.NewConnectionError\n
Run Code Online (Sandbox Code Playgroud)\nurllib3.util.Retry
name中有一个参数raise_on_status
,默认为True
. 如果成功False
,则urllib3.exceptions.MaxRetryError
不会被raise
响应。\n如果没有异常,raise
则可以肯定响应已到达。现在,将块中的块包裹response.raise_for_status
在另一个块中变得很容易。else
try
try
我已更改except RetryError
为except Exception
捕获其他异常。
import requests\nfrom requests.adapters import HTTPAdapter\nfrom requests.packages.urllib3.util.retry import Retry\nfrom requests.exceptions import RetryError\n\n# DEFAULT_ALLOWED_METHODS = frozenset({'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PUT', 'TRACE'})\n# Default methods to be used for allowed_methods\n# RETRY_AFTER_STATUS_CODES = frozenset({413, 429, 503})\n# Default status codes to be used for status_forcelist\n\nHTTP_RETRY_LIMIT = 3\nHTTP_BACKOFF_FACTOR = 0.2\n\nretry_strategy = Retry(\n total=HTTP_RETRY_LIMIT,\n backoff_factor=HTTP_BACKOFF_FACTOR,\n raise_on_status=False,\n)\nadapter = HTTPAdapter(max_retries=retry_strategy)\nhttp = requests.Session()\nhttp.mount("https://", adapter)\nhttp.mount("http://", adapter)\ntry:\n response = http.get("https://httpbin.org/status/503")\nexcept Exception as err:\n print(err)\nelse:\n try:\n response.raise_for_status()\n except Exception as e:\n # Do logic with err to perform error handling & logging.\n print(response.reason)\n # Or\n # print(e.response.reason)\n else:\n print(response.text)\n
Run Code Online (Sandbox Code Playgroud)\n测试;
\n# https://httpbin.org/user-agent\n\xe2\x9e\x9c python requests_retry.py\n{\n "user-agent": "python-requests/2.28.1"\n}\n\n# url = https://httpbin.org/status/503\n\xe2\x9e\x9c python requests_retry.py\nSERVICE UNAVAILABLE\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
1693 次 |
最近记录: |