Reputation: 535
I would like to know the cause of the issue when my get or post have error responses until maximum retries are exceeded.
I have an example test below. This throws a MaxRetriesError as expected. However, the original HTTPError seems to be lost.
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)
The Traceback shows the following information, it only goes back as far as the last RetryError and not to the HTTPError. The exception's string does mention the response code but parsing error message strings is not a robust approach.
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
Upvotes: 5
Views: 4193
Reputation: 535
I have found that I can see the original error if I tell Retries not to raise its own error (raise_on_status=False), but then inspect the last response instead. See modified code below.
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)
This results in:
------------------------------------------------------------- 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
Upvotes: 5