Skip to content
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

Does not set status codes on operation errors #15

Closed
larkee opened this issue Mar 23, 2020 · 2 comments · Fixed by #86
Closed

Does not set status codes on operation errors #15

larkee opened this issue Mar 23, 2020 · 2 comments · Fixed by #86
Assignees
Labels
priority: p2 Moderately-important priority. Fix may not be included in next release. 🚨 This issue needs some love. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.

Comments

@larkee
Copy link

larkee commented Mar 23, 2020

Raised in a Cloud Spanner issue, the returned GoogleAPICallError has a code and grpc_status_code of None.

The issue seems to be at:
https://github.com/googleapis/python-api-core/blob/master/google/api_core/operation.py#L135

The GoogleAPICallError constructor does not set the code from the errors argument so the error code contained within it is being lost.

@yoshi-automation yoshi-automation added the triage me I really want to be triaged. label Mar 23, 2020
@skuruppu
Copy link

CC @odeke-em and @skuruppu

@busunkim96 busunkim96 self-assigned this Mar 24, 2020
@busunkim96 busunkim96 added priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. and removed triage me I really want to be triaged. labels Mar 24, 2020
@yoshi-automation yoshi-automation added 🚨 This issue needs some love. and removed 🚨 This issue needs some love. labels Jun 22, 2020
@yoshi-automation yoshi-automation added the 🚨 This issue needs some love. label Sep 19, 2020
@busunkim96
Copy link
Contributor

I can get the code into the Exception by tweaking the bit of code @larkee highlighted to use from_grpc_status

            elif self._operation.HasField("error"):
                exception = exceptions.from_grpc_status(
                    status_code=self._operation.error.code,
                    message=self._operation.error.message,
                    errors=(self._operation.error,),
                    response=self._operation,
                )

                self.set_exception(exception)

Even after that change I seemed to always get GoogleAPICallError instead of one of the more specific exception types.

class FailedPrecondition(BadRequest):
"""Exception mapping a :attr:`grpc.StatusCode.FAILED_PRECONDITION`
error."""
grpc_status_code = grpc.StatusCode.FAILED_PRECONDITION if grpc is not None else None

The root cause seems to be that the dict that maps status codes to exception types expects grpc.StatusCode (not ints).

>>> from google.api_core import exceptions
>>> exceptions._GRPC_CODE_TO_EXCEPTION
{<StatusCode.INVALID_ARGUMENT: (3, 'invalid argument')>: <class 'google.api_core.exceptions.InvalidArgument'>, <StatusCode.FAILED_PRECONDITION: (9, 'failed precondition')>: <class 'google.api_core.exceptions.FailedPrecondition'>, <StatusCode.OUT_OF_RANGE: (11, 'out of range')>: <class 'google.api_core.exceptions.OutOfRange'>, <StatusCode.UNAUTHENTICATED: (16, 'unauthenticated')>: <class 'google.api_core.exceptions.Unauthenticated'>, <StatusCode.PERMISSION_DENIED: (7, 'permission denied')>: <class 'google.api_core.exceptions.PermissionDenied'>, <StatusCode.NOT_FOUND: (5, 'not found')>: <class 'google.api_core.exceptions.NotFound'>, <StatusCode.ALREADY_EXISTS: (6, 'already exists')>: <class 'google.api_core.exceptions.AlreadyExists'>, <StatusCode.ABORTED: (10, 'aborted')>: <class 'google.api_core.exceptions.Aborted'>, <StatusCode.RESOURCE_EXHAUSTED: (8, 'resource exhausted')>: <class 'google.api_core.exceptions.ResourceExhausted'>, <StatusCode.CANCELLED: (1, 'cancelled')>: <class 'google.api_core.exceptions.Cancelled'>, <StatusCode.INTERNAL: (13, 'internal')>: <class 'google.api_core.exceptions.InternalServerError'>, <StatusCode.UNKNOWN: (2, 'unknown')>: <class 'google.api_core.exceptions.Unknown'>, <StatusCode.DATA_LOSS: (15, 'data loss')>: <class 'google.api_core.exceptions.DataLoss'>, <StatusCode.UNIMPLEMENTED: (12, 'unimplemented')>: <class 'google.api_core.exceptions.MethodNotImplemented'>, <StatusCode.UNAVAILABLE: (14, 'unavailable')>: <class 'google.api_core.exceptions.ServiceUnavailable'>, <StatusCode.DEADLINE_EXCEEDED: (4, 'deadline exceeded')>: <class 'google.api_core.exceptions.DeadlineExceeded'>}

It wasn't clear to me how to get the enum from an int, so I opened https://groups.google.com/forum/#!topic/grpc-io/EdIXjMEaOyw.

busunkim96 added a commit that referenced this issue Oct 6, 2020
Fixes #15 🦕

Errors raised by long running operations are currently always type GoogleAPICallError. Use the status code to create a more specific exception type.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: p2 Moderately-important priority. Fix may not be included in next release. 🚨 This issue needs some love. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants