Skip to content

Commit

Permalink
Handle JSON decode error when parsing error response in client (#35)
Browse files Browse the repository at this point in the history
* handle JSON decode error when parsing error response

* catch only JSONDecodeError

* raise exception from None

* handle errors from intermediate proxies in client

Co-authored-by: Chad Wagner <[email protected]>
  • Loading branch information
chadawagner and Chad Wagner authored Dec 9, 2021
1 parent 77bc2a2 commit 53ca044
Showing 1 changed file with 43 additions and 1 deletion.
44 changes: 43 additions & 1 deletion twirp/client.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import requests

from . import exceptions
Expand All @@ -22,8 +23,10 @@ def _make_request(self, *args, url, ctx, request, response_obj, **kwargs):
response = response_obj()
response.ParseFromString(resp.content)
return response
else:
try:
raise exceptions.TwirpServerException.from_json(resp.json())
except json.JSONDecodeError:
raise self._twirp_error_from_intermediary(resp) from None
# Todo: handle error
except requests.exceptions.Timeout as e:
raise exceptions.TwirpServerException(
Expand All @@ -37,3 +40,42 @@ def _make_request(self, *args, url, ctx, request, response_obj, **kwargs):
message=str(e),
meta={"original_exception": e},
)

@staticmethod
def _twirp_error_from_intermediary(resp):
# see https://twitchtv.github.io/twirp/docs/errors.html#http-errors-from-intermediary-proxies
meta = {
'http_error_from_intermediary': 'true',
'status_code': str(resp.status_code),
}

if resp.is_redirect:
# twirp uses POST which should not redirect
code = errors.Errors.Internal
location = resp.headers.get('location')
message = 'unexpected HTTP status code %d "%s" received, Location="%s"' % (
resp.status_code,
resp.reason,
location,
)
meta['location'] = location

else:
code = {
400: errors.Errors.Internal, # JSON response should have been returned
401: errors.Errors.Unauthenticated,
403: errors.Errors.PermissionDenied,
404: errors.Errors.BadRoute,
429: errors.Errors.ResourceExhausted,
502: errors.Errors.Unavailable,
503: errors.Errors.Unavailable,
504: errors.Errors.Unavailable,
}.get(resp.status_code, errors.Errors.Unknown)

message = 'Error from intermediary with HTTP status code %d "%s"' % (
resp.status_code,
resp.reason,
)
meta['body'] = resp.text

return exceptions.TwirpServerException(code=code, message=message, meta=meta)

0 comments on commit 53ca044

Please sign in to comment.