From 1cf227055c16f52796674ad6c88de5cafcee122b Mon Sep 17 00:00:00 2001 From: David Dv Schmidt Date: Thu, 2 Feb 2023 10:55:51 +0100 Subject: Don't raise_for_status if status_code of response is in allowable_codes --- requests_cache/session.py | 5 ++++- tests/conftest.py | 4 ++++ tests/unit/test_session.py | 43 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/requests_cache/session.py b/requests_cache/session.py index c0e2563..c2eaa74 100644 --- a/requests_cache/session.py +++ b/requests_cache/session.py @@ -253,7 +253,10 @@ class CacheMixin(MIXIN_BASE): logger.debug('Stale response; attempting to re-send request') try: response = self._send_and_cache(request, actions, cached_response, **kwargs) - if self.settings.stale_if_error: + if ( + self.settings.stale_if_error + and response.status_code not in self.settings.allowable_codes + ): response.raise_for_status() return response except Exception: diff --git a/tests/conftest.py b/tests/conftest.py index bb69fd5..c91d6db 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -78,6 +78,7 @@ MOCKED_URL_REDIRECT_TARGET = 'http+mock://requests-cache.com/redirect_target' MOCKED_URL_VARY = 'http+mock://requests-cache.com/vary' MOCKED_URL_404 = 'http+mock://requests-cache.com/nonexistent' MOCKED_URL_500 = 'http+mock://requests-cache.com/answer?q=this-statement-is-false' +MOCKED_URL_200_404 = 'http+mock://requests-cache.com/200-404' MOCK_PROTOCOLS = ['mock://', 'http+mock://', 'https+mock://'] CACHE_NAME = 'pytest_cache' @@ -219,6 +220,9 @@ def get_mock_adapter() -> Adapter: ) adapter.register_uri(ANY_METHOD, MOCKED_URL_404, status_code=404) adapter.register_uri(ANY_METHOD, MOCKED_URL_500, status_code=500) + adapter.register_uri( + ANY_METHOD, MOCKED_URL_200_404, [{"status_code": 200}, {"status_code": 404}] + ) return adapter diff --git a/tests/unit/test_session.py b/tests/unit/test_session.py index 72c6977..7ed2c1b 100644 --- a/tests/unit/test_session.py +++ b/tests/unit/test_session.py @@ -22,6 +22,7 @@ from requests_cache.backends.base import DESERIALIZE_ERRORS from requests_cache.policy.expiration import DO_NOT_CACHE, EXPIRE_IMMEDIATELY, NEVER_EXPIRE from tests.conftest import ( MOCKED_URL, + MOCKED_URL_200_404, MOCKED_URL_404, MOCKED_URL_500, MOCKED_URL_ETAG, @@ -384,16 +385,39 @@ def test_stale_if_error__exception(mock_session): def test_stale_if_error__error_code(mock_session): - """With stale_if_error, expect to get old cache data if a response has an error status code""" + """With stale_if_error, expect to get old cache data if a response has an error status code, + that is not in allowable_codes. + """ + mock_session.settings.stale_if_error = True + mock_session.settings.expire_after = 1 + mock_session.settings.allowable_codes = (200,) + + assert mock_session.get(MOCKED_URL_200_404).status_code == 200 + + sleep(1) + + response = mock_session.get(MOCKED_URL_200_404) + assert response.status_code == 200 + assert response.from_cache is True + assert response.is_expired is True + + +def test_stale_if_error__error_code_in_allowable_codes(mock_session): + """With stale_if_error, expect to get the failed response if a response has an error status code, + that is in allowable_codes. + """ mock_session.settings.stale_if_error = True mock_session.settings.expire_after = 1 mock_session.settings.allowable_codes = (200, 404) - assert mock_session.get(MOCKED_URL_404).from_cache is False + assert mock_session.get(MOCKED_URL_200_404).status_code == 200 sleep(1) - response = mock_session.get(MOCKED_URL_404) - assert response.from_cache is True and response.is_expired is True + + response = mock_session.get(MOCKED_URL_200_404) + assert response.status_code == 404 + assert response.from_cache is False + assert response.is_expired is False def test_stale_if_error__max_stale(mock_session): @@ -402,15 +426,16 @@ def test_stale_if_error__max_stale(mock_session): """ mock_session.settings.stale_if_error = timedelta(seconds=15) mock_session.settings.expire_after = datetime.utcnow() - timedelta(seconds=10) - mock_session.settings.allowable_codes = (200, 404) - mock_session.get(MOCKED_URL_404).from_cache + mock_session.settings.allowable_codes = (200,) + mock_session.get(MOCKED_URL_200_404).from_cache - response = mock_session.get(MOCKED_URL_404) - assert response.from_cache is True and response.is_expired is True + response = mock_session.get(MOCKED_URL_200_404) + assert response.from_cache is True + assert response.is_expired is True mock_session.settings.stale_if_error = 5 with pytest.raises(HTTPError): - mock_session.get(MOCKED_URL_404) + mock_session.get(MOCKED_URL_200_404) def test_old_data_on_error(): -- cgit v1.2.1