-
Notifications
You must be signed in to change notification settings - Fork 89
feat: Add support for creating exceptions from an asynchronous response #688
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
2fc2b35
573413a
9c76b5f
2373149
dd7b5d1
f7ebadd
be83346
b477772
cd13bdf
324a2a0
cabb338
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -476,22 +476,31 @@ def from_http_status(status_code, message, **kwargs): | |
return error | ||
|
||
|
||
def from_http_response(response): | ||
"""Create a :class:`GoogleAPICallError` from a :class:`requests.Response`. | ||
def _format_error_message(error, method, url): | ||
method = method.upper() | ||
message = "{method} {url}: {error}".format( | ||
method=method, | ||
url=url, | ||
ohmayr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
error=error, | ||
) | ||
return message | ||
|
||
|
||
def format_http_response_error(response, method, url, payload=None): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: add type hints There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. addressed with a comment. |
||
"""Create a :class:`GoogleAPICallError` from a google auth rest response. | ||
|
||
Args: | ||
response (requests.Response): The HTTP response. | ||
response Union[google.auth.transport.Response, google.auth.aio.transport.Response]: The HTTP response. | ||
method Optional(str): The HTTP request method. | ||
url Optional(str): The HTTP request url. | ||
payload Optional(str): The HTTP response payload. If not passed in, it is read from response for a response type of google.auth.transport.Response. | ||
|
||
Returns: | ||
GoogleAPICallError: An instance of the appropriate subclass of | ||
:class:`GoogleAPICallError`, with the message and errors populated | ||
from the response. | ||
""" | ||
try: | ||
payload = response.json() | ||
except ValueError: | ||
payload = {"error": {"message": response.text or "unknown error"}} | ||
|
||
payload = {} if not payload else payload | ||
error_message = payload.get("error", {}).get("message", "unknown error") | ||
errors = payload.get("error", {}).get("errors", ()) | ||
# In JSON, details are already formatted in developer-friendly way. | ||
|
@@ -504,12 +513,7 @@ def from_http_response(response): | |
) | ||
) | ||
error_info = error_info[0] if error_info else None | ||
|
||
message = "{method} {url}: {error}".format( | ||
method=response.request.method, | ||
url=response.request.url, | ||
error=error_message, | ||
) | ||
message = _format_error_message(error_message, method, url) | ||
|
||
exception = from_http_status( | ||
response.status_code, | ||
|
@@ -522,6 +526,26 @@ def from_http_response(response): | |
return exception | ||
|
||
|
||
def from_http_response(response): | ||
"""Create a :class:`GoogleAPICallError` from a :class:`requests.Response`. | ||
|
||
Args: | ||
response (requests.Response): The HTTP response. | ||
|
||
Returns: | ||
GoogleAPICallError: An instance of the appropriate subclass of | ||
:class:`GoogleAPICallError`, with the message and errors populated | ||
from the response. | ||
""" | ||
try: | ||
payload = response.json() | ||
except ValueError: | ||
payload = {"error": {"message": response.text or "unknown error"}} | ||
return format_http_response_error( | ||
response, response.request.method, response.request.url, payload | ||
) | ||
|
||
|
||
def exception_class_for_grpc_status(status_code): | ||
"""Return the exception class for a specific :class:`grpc.StatusCode`. | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,7 @@ def wrap_method( | |
default_timeout=None, | ||
default_compression=None, | ||
client_info=client_info.DEFAULT_CLIENT_INFO, | ||
kind="grpc", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, and when we call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's correct! Note to myself to update the default value to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. addressed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update the PR description with the right default value. |
||
): | ||
"""Wrap an async RPC method with common behavior. | ||
|
||
|
@@ -40,7 +41,8 @@ def wrap_method( | |
and ``compression`` arguments and applies the common error mapping, | ||
retry, timeout, metadata, and compression behavior to the low-level RPC method. | ||
""" | ||
func = grpc_helpers_async.wrap_errors(func) | ||
if kind == "grpc": | ||
func = grpc_helpers_async.wrap_errors(func) | ||
|
||
metadata = [client_info.to_grpc_metadata()] if client_info is not None else None | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.