Skip to content

Commit

Permalink
Merge pull request #98 from maxmind/greg/v4.1.0
Browse files Browse the repository at this point in the history
Prepare for 4.1.0
  • Loading branch information
horgh authored Sep 25, 2020
2 parents 2305048 + dcee069 commit 477296f
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 7 deletions.
4 changes: 3 additions & 1 deletion HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
History
-------

4.1.0
4.1.0 (2020-09-25)
++++++++++++++++++

* Added the ``is_residential_proxy`` attribute to ``geoip2.model.AnonymousIP``
and ``geoip2.record.Traits``.
* ``HTTPError`` now provides the decoded response content in the
``decoded_content`` attribute. Requested by Oleg Serbokryl. GitHub #95.

4.0.2 (2020-07-28)
++++++++++++++++++
Expand Down
8 changes: 7 additions & 1 deletion geoip2/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,21 @@ class HTTPError(GeoIP2Error):
:ivar http_status: The HTTP status code returned
:ivar uri: The URI queried
:ivar decoded_content: The decoded response content
"""

def __init__(
self, message: str, http_status: Optional[int] = None, uri: Optional[str] = None
self,
message: str,
http_status: Optional[int] = None,
uri: Optional[str] = None,
decoded_content: Optional[str] = None,
) -> None:
super().__init__(message)
self.http_status = http_status
self.uri = uri
self.decoded_content = decoded_content


class InvalidRequestError(GeoIP2Error):
Expand Down
20 changes: 15 additions & 5 deletions geoip2/webservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ def _exception_for_error(
if 400 <= status < 500:
return self._exception_for_4xx_status(status, content_type, body, uri)
if 500 <= status < 600:
return self._exception_for_5xx_status(status, uri)
return self._exception_for_non_200_status(status, uri)
return self._exception_for_5xx_status(status, uri, body)
return self._exception_for_non_200_status(status, uri, body)

def _exception_for_4xx_status(
self, status: int, content_type: str, body: str, uri: str
Expand All @@ -123,13 +123,15 @@ def _exception_for_4xx_status(
"Received a %(status)i error for %(uri)s " "with no body." % locals(),
status,
uri,
body,
)
if content_type.find("json") == -1:
return HTTPError(
"Received a %i for %s with the following "
"body: %s" % (status, uri, str(content_type)),
status,
uri,
body,
)
try:
decoded_body = json.loads(body)
Expand All @@ -139,16 +141,18 @@ def _exception_for_4xx_status(
" not include the expected JSON body: " % locals() + ", ".join(ex.args),
status,
uri,
body,
)
else:
if "code" in body and "error" in body:
if "code" in decoded_body and "error" in decoded_body:
return self._exception_for_web_service_error(
decoded_body.get("error"), decoded_body.get("code"), status, uri
)
return HTTPError(
"Response contains JSON but it does not specify " "code or error keys",
status,
uri,
body,
)

@staticmethod
Expand Down Expand Up @@ -180,20 +184,26 @@ def _exception_for_web_service_error(
return InvalidRequestError(message, code, status, uri)

@staticmethod
def _exception_for_5xx_status(status: int, uri: str) -> HTTPError:
def _exception_for_5xx_status(
status: int, uri: str, body: Optional[str]
) -> HTTPError:
return HTTPError(
"Received a server error (%(status)i) for " "%(uri)s" % locals(),
status,
uri,
body,
)

@staticmethod
def _exception_for_non_200_status(status: int, uri: str) -> HTTPError:
def _exception_for_non_200_status(
status: int, uri: str, body: Optional[str]
) -> HTTPError:
return HTTPError(
"Received a very surprising HTTP status "
"(%(status)i) for %(uri)s" % locals(),
status,
uri,
body,
)


Expand Down

0 comments on commit 477296f

Please sign in to comment.