From 5bb18658b23fdefc7f2c07604701a417a6788668 Mon Sep 17 00:00:00 2001 From: Charly C Date: Tue, 20 Aug 2019 19:21:30 +0200 Subject: [PATCH] Fix automatic retries of failed requests (#605) * fix automatic retries of failed requests * fix `test_retry_codes_until_exceeded` If the number of retries is set to 3, then the total number of requests should be 4: the initial one + the three retries. * improve consistency between HTTP clients This commit modifies `PycurlClient` to set the `should_retry` attribute of `APIConnectionError` exceptions, like `RequestsClient` does. --- stripe/http_client.py | 8 +++++--- tests/test_http_client.py | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/stripe/http_client.py b/stripe/http_client.py index b19342ad3..ca3a2915f 100644 --- a/stripe/http_client.py +++ b/stripe/http_client.py @@ -119,7 +119,6 @@ def request_with_retries(self, method, url, headers, post_data=None): request_start = _now_ms() try: - num_retries += 1 response = self.request(method, url, headers, post_data) connection_error = None except error.APIConnectionError as e: @@ -132,7 +131,7 @@ def request_with_retries(self, method, url, headers, post_data=None): "Encountered a retryable error %s" % connection_error.user_message ) - + num_retries += 1 sleep_time = self._sleep_time_seconds(num_retries) util.log_info( ( @@ -494,6 +493,7 @@ def _handle_request_error(self, e): "https://twitter.com/stripestatus, or let us know at " "support@stripe.com." ) + should_retry = True elif e.args[0] in [pycurl.E_SSL_CACERT, pycurl.E_SSL_PEER_CERTIFICATE]: msg = ( "Could not verify Stripe's SSL certificate. Please make " @@ -501,14 +501,16 @@ def _handle_request_error(self, e): "If this problem persists, let us know at " "support@stripe.com." ) + should_retry = False else: msg = ( "Unexpected error communicating with Stripe. If this " "problem persists, let us know at support@stripe.com." ) + should_retry = False msg = textwrap.fill(msg) + "\n\n(Network error: " + e.args[1] + ")" - raise error.APIConnectionError(msg) + raise error.APIConnectionError(msg, should_retry=should_retry) def _get_proxy(self, url): if self._proxy: diff --git a/tests/test_http_client.py b/tests/test_http_client.py index 498b07e86..16dd5a378 100644 --- a/tests/test_http_client.py +++ b/tests/test_http_client.py @@ -436,10 +436,10 @@ def test_retry_codes(self, mock_retry, response, check_call_numbers): def test_retry_codes_until_exceeded( self, mock_retry, response, check_call_numbers ): - mock_retry(responses=[response(code=409)] * self.max_retries()) + mock_retry(responses=[response(code=409)] * (self.max_retries() + 1)) _, code, _ = self.make_request() assert code == 409 - check_call_numbers(self.max_retries()) + check_call_numbers(self.max_retries() + 1) @pytest.fixture def connection_error(self, session):