Skip to content

Commit eea0f5b

Browse files
committed
Raise HTTPError in case of HTTP 5XX responses.
It is misleading to raise a MissingTokenError when the server has returned an HTTP server error. Instead, raise requests.exceptions.HTTPError if the server has returned an HTTP 5XX server error. Prior PR conversation in PR #217 indicates that the maintainers do not want to raise on 4XX errors due to certain providers using those responses to send data. So we need a custom handler with a slight variation on the built-in requests.models.Response.raise_for_status().
1 parent 46f886c commit eea0f5b

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

requests_oauthlib/oauth2_session.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from oauthlib.oauth2 import LegacyApplicationClient
88
from oauthlib.oauth2 import TokenExpiredError, is_secure_transport
99
import requests
10+
from requests.exceptions import HTTPError
1011

1112
log = logging.getLogger(__name__)
1213

@@ -363,6 +364,8 @@ def fetch_token(
363364
log.debug("Invoking hook %s.", hook)
364365
r = hook(r)
365366

367+
self._raise_for_5xx(response=r)
368+
366369
self._client.parse_request_body_response(r.text, scope=self.scope)
367370
self.token = self._client.token
368371
log.debug("Obtained token %s.", self.token)
@@ -449,6 +452,8 @@ def refresh_token(
449452
log.debug("Invoking hook %s.", hook)
450453
r = hook(r)
451454

455+
self._raise_for_5xx(response=r)
456+
452457
self.token = self._client.parse_request_body_response(r.text, scope=self.scope)
453458
if not "refresh_token" in self.token:
454459
log.debug("No new refresh token given. Re-using old.")
@@ -538,3 +543,37 @@ def register_compliance_hook(self, hook_type, hook):
538543
"Hook type %s is not in %s.", hook_type, self.compliance_hook
539544
)
540545
self.compliance_hook[hook_type].add(hook)
546+
547+
def _raise_for_5xx(self, response: requests.models.Response) -> None:
548+
"""
549+
Raise requests.HTTPError if response is an HTTP 5XX error.
550+
551+
Just like the existing Response.raise_for_status() but ignores 4XX
552+
errors.
553+
554+
:param response: HTTP response object from requests
555+
Raises :class:`requests.exceptions.HTTPError`, if a 5XX error occurred.
556+
"""
557+
http_error_msg = ''
558+
if isinstance(response.reason, bytes):
559+
# We attempt to decode utf-8 first because some servers
560+
# choose to localize their reason strings. If the string
561+
# isn't utf-8, we fall back to iso-8859-1 for all other
562+
# encodings. (See psf/requests PR #3538)
563+
try:
564+
reason = response.reason.decode('utf-8')
565+
except UnicodeDecodeError:
566+
reason = response.reason.decode('iso-8859-1')
567+
else:
568+
reason = response.reason
569+
570+
if 400 <= response.status_code < 500:
571+
pass # ignored
572+
573+
elif 500 <= response.status_code < 600:
574+
http_error_msg = u'%s Server Error: %s for url: %s' % (
575+
response.status_code, reason, response.url
576+
)
577+
578+
if http_error_msg:
579+
raise HTTPError(http_error_msg, response=response)

0 commit comments

Comments
 (0)