当get或post出现错误响应直到超过最大重试次数时,我想知道问题的原因。
我在下面有一个示例测试。如预期的那样,这将引发MaxRetriesError。但是,原始的HTTPError似乎丢失了。
from requests import Session, exceptions
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
from unittest import TestCase
import logging
class TestRequests(TestCase):
def test_retries(self):
session = Session()
retries = Retry(total=5,
backoff_factor=0.1,
status_forcelist=[500, 502, 503, 504],
method_whitelist=frozenset(['GET', 'POST']))
session.mount('https://', HTTPAdapter(max_retries=retries))
session.mount('http://', HTTPAdapter(max_retries=retries))
try:
result = session.get('https://httpbin.org/status/500',
stream=True,
timeout=2)
print(result)
except exceptions.HTTPError as e:
logging.error('http', exc_info=e)
except exceptions.RetryError as e:
logging.error('retry', exc_info=e)
Traceback显示以下信息,它仅返回到最后一个RetryError,而不返回到HTTPError。异常的字符串确实提到了响应代码,但是解析错误消息字符串并不是一种可靠的方法。
ERROR:root:retry
Traceback (most recent call last):
File "/home/giles/venv/gphotos-sync3/lib/python3.6/site-packages/requests/adapters.py", line 449, in send
timeout=timeout
File "/home/giles/venv/gphotos-sync3/lib/python3.6/site-packages/urllib3/connectionpool.py", line 731, in urlopen
body_pos=body_pos, **response_kw)
File "/home/giles/venv/gphotos-sync3/lib/python3.6/site-packages/urllib3/connectionpool.py", line 731, in urlopen
body_pos=body_pos, **response_kw)
File "/home/giles/venv/gphotos-sync3/lib/python3.6/site-packages/urllib3/connectionpool.py", line 731, in urlopen
body_pos=body_pos, **response_kw)
[Previous line repeated 2 more times]
File "/home/giles/venv/gphotos-sync3/lib/python3.6/site-packages/urllib3/connectionpool.py", line 711, in urlopen
retries = retries.increment(method, url, response=response, _pool=self)
File "/home/giles/venv/gphotos-sync3/lib/python3.6/site-packages/urllib3/util/retry.py", line 398, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='httpbin.org', port=443): Max retries exceeded with url: /status/500 (Caused by ResponseError('too many 500 error responses',))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/giles/github/gphotos-sync/test/test_requests.py", line 36, in test_retries
timeout=2)
File "/home/giles/venv/gphotos-sync3/lib/python3.6/site-packages/requests/sessions.py", line 546, in get
return self.request('GET', url, **kwargs)
File "/home/giles/venv/gphotos-sync3/lib/python3.6/site-packages/requests/sessions.py", line 533, in request
resp = self.send(prep, **send_kwargs)
File "/home/giles/venv/gphotos-sync3/lib/python3.6/site-packages/requests/sessions.py", line 646, in send
r = adapter.send(request, **kwargs)
File "/home/giles/venv/gphotos-sync3/lib/python3.6/site-packages/requests/adapters.py", line 507, in send
raise RetryError(e, request=request)
requests.exceptions.RetryError: HTTPSConnectionPool(host='httpbin.org', port=443): Max retries exceeded with url: /status/500 (Caused by ResponseError('too many 500 error responses',))
Ran 1 test in 4.092s
OK
答案 0 :(得分:0)
我发现,如果我告诉Retries不要提出自己的错误(raise_on_status = False),而是检查最后一个响应,则可以看到原始错误。请参阅下面的修改代码。
from requests import Session, exceptions
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
from urllib3.exceptions import MaxRetryError
from unittest import TestCase
import logging
class TestRequests(TestCase):
def test_retries(self):
session = Session()
retries = Retry(total=5,
backoff_factor=0.1,
status_forcelist=[500, 502, 503, 504],
method_whitelist=frozenset(['GET', 'POST']),
raise_on_status=False)
session.mount('https://', HTTPAdapter(max_retries=retries))
session.mount('http://', HTTPAdapter(max_retries=retries))
try:
result = session.get('https://httpbin.org/status/500',
stream=True,
timeout=2)
print(result)
result.raise_for_status()
except exceptions.HTTPError as e:
logging.error('http', exc_info=e)
except MaxRetryError as e:
logging.error('retry', exc_info=e)
结果是:
------------------------------------------------------------- Captured stdout call --------------------------------------------------------------
<Response [500]>
--------------------------------------------------------------- Captured log call ---------------------------------------------------------------
test-requests.py 30 ERROR http
Traceback (most recent call last):
File "/home/hgv27681/github/tests/test-requests.py", line 27, in test_retries
result.raise_for_status()
File "/home/hgv27681/github/venv3/lib/python3.6/site-packages/requests/models.py", line 940, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 500 Server Error: INTERNAL SERVER ERROR for url: https://httpbin.org/status/500