Skip to content
This repository has been archived by the owner on Mar 20, 2018. It is now read-only.

Commit

Permalink
Replacing ValueError with InvalidArgumentError in google.gax.errors.c…
Browse files Browse the repository at this point in the history
…reate_error(). (#196)

This new class inherits from both GaxError and ValueError to keep
from breaking existing clients.

By wrapping an `INVALID_ARGUMENT` in a `ValueError`, the impl. was losing
information by "stringify"-ing the wrapped exception.

See #132 for change that introduced the `ValueError` behavior.
  • Loading branch information
dhermes authored and Jon Wayne Parrott committed Jul 31, 2017
1 parent 6ceb0d8 commit 58e8c2f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 11 deletions.
36 changes: 26 additions & 10 deletions google/gax/errors.py
Expand Up @@ -52,26 +52,42 @@ def __str__(self):
if not self.cause:
return msg

return 'GaxError({}, caused by {})'.format(msg, self.cause)
return '{}({}, caused by {})'.format(
self.__class__.__name__, msg, self.cause)


def create_error(msg, cause=None):
"""Creates an error.
Uses a Python built-in exception if one is available, and a
GaxError otherwise.
class InvalidArgumentError(ValueError, GaxError):
"""GAX exception class for ``INVALID_ARGUMENT`` errors.
Attributes:
msg (string): describes the error that occurred.
cause (Exception, optional): the exception raised by a lower
layer of the RPC stack (for example, gRPC) that caused this
exception, or None if this exception originated in GAX.
"""
if config.NAME_STATUS_CODES.get(
config.exc_to_code(cause)) == 'INVALID_ARGUMENT':
return ValueError('{}: {}'.format(msg, cause))

def __init__(self, msg, cause=None):
GaxError.__init__(self, msg, cause=cause)


def create_error(msg, cause=None):
"""Creates a ``GaxError`` or subclass.
Attributes:
msg (string): describes the error that occurred.
cause (Exception, optional): the exception raised by a lower
layer of the RPC stack (for example, gRPC) that caused this
exception, or None if this exception originated in GAX.
Returns:
.GaxError: The exception that wraps ``cause``.
"""
status_code = config.exc_to_code(cause)
status_name = config.NAME_STATUS_CODES.get(status_code)
if status_name == 'INVALID_ARGUMENT':
return InvalidArgumentError(msg, cause=cause)
else:
return GaxError(msg, cause)
return GaxError(msg, cause=cause)


class RetryError(GaxError):
Expand Down
9 changes: 8 additions & 1 deletion tests/test_api_callable.py
Expand Up @@ -438,6 +438,7 @@ def other_error_func(*dummy_args, **dummy_kwargs):
self.assertRaises(AnotherException, other_error_callable, None)

def test_wrap_value_error(self):
from google.gax.errors import InvalidArgumentError

invalid_attribute_exc = grpc.RpcError()
invalid_attribute_exc.code = lambda: grpc.StatusCode.INVALID_ARGUMENT
Expand All @@ -447,4 +448,10 @@ def value_error_func(*dummy_args, **dummy_kwargs):

value_error_callable = api_callable.create_api_call(
value_error_func, _CallSettings())
self.assertRaises(ValueError, value_error_callable, None)

with self.assertRaises(ValueError) as exc_info:
value_error_callable(None)

self.assertIsInstance(exc_info.exception, InvalidArgumentError)
self.assertEqual(exc_info.exception.args, (u'RPC failed',))
self.assertIs(exc_info.exception.cause, invalid_attribute_exc)

0 comments on commit 58e8c2f

Please sign in to comment.