Skip to content

Commit

Permalink
Bugfix/exceptions wrap responses (#93)
Browse files Browse the repository at this point in the history
* -fix exceptions to wrap the response correctly
-adjust tests

* - argument naming consistency
- clarify docstring
- show inherited members in Exceptions methoddocs

* - update changelog
- add test that response is what we expect
  • Loading branch information
timabrmsn committed Apr 22, 2020
1 parent 7a11f4a commit 52d7991
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 14 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
The intended audience of this file is for py42 consumers -- as such, changes that don't affect
how a consumer would use the library (e.g. adding unit tests, updating documentation, etc) are not captured here.

## Unreleased

### Changed

- Exceptions that inherit from `Py42HTTPError` now return the original `requests.Response` object on the exception's
`.response` property instead of a string representation of the `HTTPError` that was raised.

## 1.0.0 - 2020-04-21

## Changed
### Changed

- `sdk.detectionlists` methods:
- `add_cloud_aliases()` > `add_cloud_alias()`
Expand Down
2 changes: 1 addition & 1 deletion docs/methoddocs/exceptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
```eval_rst
.. automodule:: py42.exceptions
:members:
:inherited-members:
:show-inheritance:
```
20 changes: 10 additions & 10 deletions src/py42/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,50 +56,50 @@ def __init__(self, error_message):
class Py42HTTPError(Py42Error):
"""A base custom class to manage all HTTP errors raised by an API endpoint."""

def __init__(self, http_response):
message = u"Failure in HTTP call {0}".format(str(http_response))
def __init__(self, exception):
message = u"Failure in HTTP call {0}".format(str(exception))
super(Py42HTTPError, self).__init__(message)
self._response = http_response
self._response = exception.response

@property
def response(self):
"""The response containing the HTTP error."""
"""The response object containing the HTTP error details."""
return self._response


class Py42BadRequestError(Py42HTTPError):
"""A wrapper to represent an HTTP 400 error."""

def __init__(self, exception):
super(Py42BadRequestError, self).__init__(str(exception))
super(Py42BadRequestError, self).__init__(exception)


class Py42UnauthorizedError(Py42HTTPError):
"""A wrapper to represent an HTTP 401 error."""

def __init__(self, exception):
super(Py42UnauthorizedError, self).__init__(str(exception))
super(Py42UnauthorizedError, self).__init__(exception)


class Py42ForbiddenError(Py42HTTPError):
"""A wrapper to represent an HTTP 403 error."""

def __init__(self, exception):
super(Py42ForbiddenError, self).__init__(str(exception))
super(Py42ForbiddenError, self).__init__(exception)


class Py42NotFoundError(Py42HTTPError):
"""A wrapper to represent an HTTP 404 error."""

def __init__(self, exception):
super(Py42NotFoundError, self).__init__(str(exception))
super(Py42NotFoundError, self).__init__(exception)


class Py42InternalServerError(Py42HTTPError):
"""A wrapper to represent an HTTP 500 error."""

def __init__(self, exception):
super(Py42InternalServerError, self).__init__(str(exception))
super(Py42InternalServerError, self).__init__(exception)


def raise_py42_error(raised_error):
Expand All @@ -117,4 +117,4 @@ def raise_py42_error(raised_error):
elif 500 <= raised_error.response.status_code < 600:
raise Py42InternalServerError(raised_error)
else:
raise Py42HTTPError(raised_error.response)
raise Py42HTTPError(raised_error)
9 changes: 7 additions & 2 deletions tests/_internal/clients/test_detection_list_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from py42.clients.users import UserClient
from py42.exceptions import Py42BadRequestError
from requests import Response
from requests.exceptions import HTTPError


class TestDetectionListUserClient(object):
Expand All @@ -18,15 +19,19 @@ def mock_user_client(self, mock_session, user_context, py42_response):
def mock_get_by_id_fails(self, mocker, mock_session):
response = mocker.MagicMock(spec=Response)
response.status_code = 400
mock_session.post.side_effect = Py42BadRequestError(response)
exception = mocker.MagicMock(spec=HTTPError)
exception.response = response
mock_session.post.side_effect = Py42BadRequestError(exception)
return mock_session

@pytest.fixture
def mock_user_client_raises_exception(self, mocker, mock_session, user_context, py42_response):
user_client = UserClient(mock_session)
response = mocker.MagicMock(spec=Response)
response.status_code = 400
mock_session.post.side_effect = Py42BadRequestError(response)
exception = mocker.MagicMock(spec=HTTPError)
exception.response = response
mock_session.post.side_effect = Py42BadRequestError(exception)
return user_client

def test_create_posts_expected_data(self, mock_session, user_context, mock_user_client):
Expand Down
8 changes: 8 additions & 0 deletions tests/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,11 @@ def test_raise_py42_error_raises_py42_http_error(self, error_response):
error_response.response.status_code = 999
with pytest.raises(Py42HTTPError):
raise_py42_error(error_response)

@pytest.mark.parametrize("status_code", [400, 401, 403, 404, 500, 600])
def test_raise_py42_http_error_has_correct_response_type(self, error_response, status_code):
error_response.response.status_code = status_code
try:
raise_py42_error(error_response)
except Exception as e:
assert type(e.response) == type(error_response.response)

0 comments on commit 52d7991

Please sign in to comment.