From 3cac0393f453ecce67a0c268feab666470109318 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Fri, 25 Sep 2020 08:02:08 -0700 Subject: [PATCH 1/3] Check decoded JSON for keys, not body --- geoip2/webservice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geoip2/webservice.py b/geoip2/webservice.py index 2a01a7b1..3ba2bf1f 100644 --- a/geoip2/webservice.py +++ b/geoip2/webservice.py @@ -141,7 +141,7 @@ def _exception_for_4xx_status( uri, ) 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 ) From a17dc9f5786f78900f62198431475b8d98a9186d Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Fri, 25 Sep 2020 08:08:54 -0700 Subject: [PATCH 2/3] Include the decode response content in HTTPError exceptions Closes #95. --- HISTORY.rst | 2 ++ geoip2/errors.py | 8 +++++++- geoip2/webservice.py | 18 ++++++++++++++---- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index b3842e60..461e9d8e 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -8,6 +8,8 @@ History * 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) ++++++++++++++++++ diff --git a/geoip2/errors.py b/geoip2/errors.py index d3d40d9b..a1f65f2d 100644 --- a/geoip2/errors.py +++ b/geoip2/errors.py @@ -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): diff --git a/geoip2/webservice.py b/geoip2/webservice.py index 3ba2bf1f..32a1e676 100644 --- a/geoip2/webservice.py +++ b/geoip2/webservice.py @@ -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 @@ -123,6 +123,7 @@ 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( @@ -130,6 +131,7 @@ def _exception_for_4xx_status( "body: %s" % (status, uri, str(content_type)), status, uri, + body, ) try: decoded_body = json.loads(body) @@ -139,6 +141,7 @@ def _exception_for_4xx_status( " not include the expected JSON body: " % locals() + ", ".join(ex.args), status, uri, + body, ) else: if "code" in decoded_body and "error" in decoded_body: @@ -149,6 +152,7 @@ def _exception_for_4xx_status( "Response contains JSON but it does not specify " "code or error keys", status, uri, + body, ) @staticmethod @@ -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, ) From dcee0690ba27f3030d47a73bda0acdc01bde8f1f Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Fri, 25 Sep 2020 08:11:27 -0700 Subject: [PATCH 3/3] Set release date --- HISTORY.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.rst b/HISTORY.rst index 461e9d8e..bc2e278a 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -3,7 +3,7 @@ History ------- -4.1.0 +4.1.0 (2020-09-25) ++++++++++++++++++ * Added the ``is_residential_proxy`` attribute to ``geoip2.model.AnonymousIP``