Skip to content

Commit

Permalink
Merge pull request #391 from openedx/pwnage101/fix-subsidy-api-error-…
Browse files Browse the repository at this point in the history
…logging

fix: SubsidyAPIHTTPError should not drop the HTTP response error
  • Loading branch information
pwnage101 authored Jan 31, 2024
2 parents c1a4ad6 + 16790eb commit 36a5cfd
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from rest_framework import status
from rest_framework.reverse import reverse

from enterprise_access.apps.api_client.tests.test_utils import MockResponse
from enterprise_access.apps.content_assignments.constants import LearnerContentAssignmentStateChoices
from enterprise_access.apps.content_assignments.tests.factories import (
AssignmentConfigurationFactory,
Expand Down Expand Up @@ -2005,13 +2006,17 @@ def test_can_redeem_subsidy_client_http_error(self, mock_get_client):
query_params = {'content_key': test_content_key}

mock_client = mock_get_client.return_value
mock_client.list_subsidy_transactions.side_effect = HTTPError
mock_client.list_subsidy_transactions.side_effect = HTTPError(
'Fake HTTP Error Message',
response=MockResponse({'detail': 'foobar'}, status.HTTP_503_SERVICE_UNAVAILABLE),
)

response = self.client.get(self.subsidy_access_policy_can_redeem_endpoint, query_params)

assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
assert response.json() == {
'detail': 'Subsidy Transaction API error: HTTPError occurred in Subsidy API request.',
'detail': 'Subsidy Transaction API error: foobar',
'subsidy_status_code': str(status.HTTP_503_SERVICE_UNAVAILABLE),
}


Expand Down
18 changes: 15 additions & 3 deletions enterprise_access/apps/subsidy_access_policy/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,24 @@ class SubsidyAPIHTTPError(requests.exceptions.HTTPError):
"""
@property
def error_response(self):
""" Fetch the response object from the HTTPError that caused this exception. """
"""
Fetch the response object from the HTTPError that caused this exception.
Returns:
requests.models.Response or None.
"""
return self.__cause__.response # pylint: disable=no-member

def error_payload(self):
if self.error_response:
return self.error_response.json()
"""
Generate a useful error payload for logging purposes.
"""
# requests.models.Response is falsey for HTTP status codes greater than or equal to 400! We must explicitly
# check if the response object is not None before giving up on it.
if self.error_response is not None:
error_payload = self.error_response.json()
error_payload['subsidy_status_code'] = self.error_response.status_code
return error_payload
return {
'detail': str(self),
}
Expand Down

0 comments on commit 36a5cfd

Please sign in to comment.