@@ -410,8 +410,9 @@ def run_local_server(
410410 in the user's browser.
411411 redirect_uri_trailing_slash (bool): whether or not to add trailing
412412 slash when constructing the redirect_uri. Default value is True.
413- timeout_seconds (int): It will raise an error after the timeout timing
414- if there are no credentials response. The value is in seconds.
413+ timeout_seconds (int): It will raise a WSGITimeout exception after the
414+ timeout timing if there are no credentials response. The value is in
415+ seconds.
415416 When set to None there is no timeout.
416417 Default value is None.
417418 token_audience (str): Passed along with the request for an access
@@ -425,6 +426,10 @@ def run_local_server(
425426 Returns:
426427 google.oauth2.credentials.Credentials: The OAuth 2.0 credentials
427428 for the user.
429+
430+ Raises:
431+ WSGITimeout: If there is a timeout when waiting for the response from the
432+ authorization server.
428433 """
429434 wsgi_app = _RedirectWSGIApp (success_message )
430435 # Fail fast if the address is occupied
@@ -452,6 +457,10 @@ def run_local_server(
452457 local_server .timeout = timeout_seconds
453458 local_server .handle_request ()
454459
460+ if wsgi_app .last_request_uri is None :
461+ # Timeout occurred
462+ raise WSGITimeout ("Timed out waiting for response from authorization server" )
463+
455464 # Note: using https here because oauthlib is very picky that
456465 # OAuth 2.0 should only occur over https.
457466 authorization_response = wsgi_app .last_request_uri .replace ("http" , "https" )
@@ -505,3 +514,7 @@ def __call__(self, environ, start_response):
505514 start_response ("200 OK" , [("Content-type" , "text/plain; charset=utf-8" )])
506515 self .last_request_uri = wsgiref .util .request_uri (environ )
507516 return [self ._success_message .encode ("utf-8" )]
517+
518+
519+ class WSGITimeout (Exception ):
520+ """Raised when the WSGI server times out waiting for a response."""
0 commit comments