def test_from_grpc_error_non_call(): message = 'message' error = mock.create_autospec(grpc.RpcError, instance=True) error.__str__.return_value = message exception = exceptions.from_grpc_error(error) assert isinstance(exception, exceptions.GoogleAPICallError) assert exception.code is None assert exception.grpc_status_code is None assert exception.message == message assert exception.errors == [error] assert exception.response == error
def test_from_grpc_error(): message = 'message' error = mock.create_autospec(grpc.Call, instance=True) error.code.return_value = grpc.StatusCode.INVALID_ARGUMENT error.details.return_value = message exception = exceptions.from_grpc_error(error) assert isinstance(exception, exceptions.BadRequest) assert isinstance(exception, exceptions.InvalidArgument) assert exception.code == http_client.BAD_REQUEST assert exception.grpc_status_code == grpc.StatusCode.INVALID_ARGUMENT assert exception.message == message assert exception.errors == [error] assert exception.response == error
def error_remapped_callable(*args, **kwargs): try: result = callable_(*args, **kwargs) # Note: we are patching the private grpc._channel._Rendezvous._next # method as magic methods (__next__ in this case) can not be # patched on a per-instance basis (see # https://docs.python.org/3/reference/datamodel.html # #special-lookup). # In an ideal world, gRPC would return a *specific* interface # from *StreamMultiCallables, but they return a God class that's # a combination of basically every interface in gRPC making it # untenable for us to implement a wrapper object using the same # interface. result._next = _wrap_unary_errors(result._next) return result except grpc.RpcError as exc: six.raise_from(exceptions.from_grpc_error(exc), exc)
def error_remapped_callable(*args, **kwargs): try: return callable_(*args, **kwargs) except grpc.RpcError as exc: six.raise_from(exceptions.from_grpc_error(exc), exc)