diff options
author | Dan Smith <danms@us.ibm.com> | 2012-12-05 12:22:40 -0800 |
---|---|---|
committer | Dan Smith <danms@us.ibm.com> | 2012-12-06 08:31:13 -0800 |
commit | 15ae704d927ba2ecd97d29195d30d5587987e2ad (patch) | |
tree | bcca356f634c5f7a67d7f3e7b0672a8ac3e7ef72 /tests | |
parent | 2f7a7edc41d0e7b663877592aeda14e766a64241 (diff) | |
download | oslo-15ae704d927ba2ecd97d29195d30d5587987e2ad.tar.gz oslo-15ae704d927ba2ecd97d29195d30d5587987e2ad.tar.xz oslo-15ae704d927ba2ecd97d29195d30d5587987e2ad.zip |
Allow exceptions to pass over RPC silently
When one service performs an operation on behalf of another, the
act of passing back an exception (even a known one) causes a lot
of scary log messages about the (presumed to be) error case. This
patch adds a client_exceptions decorator common/rpc/common.py,
which allows RPC services to declare the list of expected exceptions
for each method. If such an exception is raised during the RPC
dispatch, it is wrapped in a ClientException so that the RPC layer
can gracefully pass it back without overly-verbose logging.
This will allow us to fix nova bug 1084707
Change-Id: I4e7b19dc730342091fd70a717065741d56da4555
Diffstat (limited to 'tests')
-rw-r--r-- | tests/unit/rpc/test_common.py | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/tests/unit/rpc/test_common.py b/tests/unit/rpc/test_common.py index 37d4f25..7489a8f 100644 --- a/tests/unit/rpc/test_common.py +++ b/tests/unit/rpc/test_common.py @@ -169,3 +169,56 @@ class RpcCommonTestCase(test_utils.BaseTestCase): def test_queue_get_for(self): self.assertEqual(rpc.queue_get_for(None, 'a', 'b'), 'a.b') self.assertEqual(rpc.queue_get_for(None, 'a', None), 'a') + + def test_client_exception(self): + e = None + try: + try: + raise ValueError() + except Exception: + raise rpc_common.ClientException() + except rpc_common.ClientException, e: + pass + + self.assertTrue(isinstance(e, rpc_common.ClientException)) + self.assertTrue(e._exc_info[1], ValueError) + + def test_catch_client_exception(self): + def naughty(param): + int(param) + + e = None + try: + rpc_common.catch_client_exception([ValueError], naughty, 'a') + except rpc_common.ClientException, e: + pass + + self.assertTrue(isinstance(e, rpc_common.ClientException)) + self.assertTrue(isinstance(e._exc_info[1], ValueError)) + + def test_catch_client_exception_other(self): + class FooException(Exception): + pass + + def naughty(): + raise FooException() + + e = None + self.assertRaises(FooException, + rpc_common.catch_client_exception, + [ValueError], naughty) + + def test_client_exceptions_decorator(self): + class FooException(Exception): + pass + + @rpc_common.client_exceptions(FooException) + def naughty(): + raise FooException() + + @rpc_common.client_exceptions(FooException) + def really_naughty(): + raise ValueError() + + self.assertRaises(rpc_common.ClientException, naughty) + self.assertRaises(ValueError, really_naughty) |