diff options
author | Kiall Mac Innes <kiall@hp.com> | 2013-03-26 16:48:39 +0000 |
---|---|---|
committer | Kiall Mac Innes <kiall@hp.com> | 2013-03-31 22:07:11 +0100 |
commit | 0912900042f777f2c31776aaedd8325e60287f33 (patch) | |
tree | f1d85f1f5f79f18b1b68f9920bc704d0857c0f81 | |
parent | 05219b89b367b077a1e1f61a2767e71f7f44665a (diff) | |
download | oslo-0912900042f777f2c31776aaedd8325e60287f33.tar.gz oslo-0912900042f777f2c31776aaedd8325e60287f33.tar.xz oslo-0912900042f777f2c31776aaedd8325e60287f33.zip |
rpc: fix positional args in remote exceptions
Fixes bug #1160475.
Positional arguments were dropped during the deserialization of
valid remote exceptions, while keyword arguments are correctly
supplied.
Change-Id: I7b95fc4ed3fb9e5c75f5711ed6aace7aa5593727
-rw-r--r-- | openstack/common/rpc/common.py | 2 | ||||
-rw-r--r-- | tests/unit/rpc/test_common.py | 25 |
2 files changed, 24 insertions, 3 deletions
diff --git a/openstack/common/rpc/common.py b/openstack/common/rpc/common.py index 42aaf09..6fb39e1 100644 --- a/openstack/common/rpc/common.py +++ b/openstack/common/rpc/common.py @@ -339,7 +339,7 @@ def deserialize_remote_exception(conf, data): if not issubclass(klass, Exception): raise TypeError("Can only deserialize Exceptions") - failure = klass(**failure.get('kwargs', {})) + failure = klass(*failure.get('args', []), **failure.get('kwargs', {})) except (AttributeError, TypeError, ImportError): return RemoteError(name, failure.get('message'), trace) diff --git a/tests/unit/rpc/test_common.py b/tests/unit/rpc/test_common.py index cb7e35d..755e2a4 100644 --- a/tests/unit/rpc/test_common.py +++ b/tests/unit/rpc/test_common.py @@ -39,8 +39,9 @@ def raise_exception(): class FakeUserDefinedException(Exception): - def __init__(self): - Exception.__init__(self, "Test Message") + def __init__(self, *args, **kwargs): + super(FakeUserDefinedException, self).__init__(*args) + self.kwargs = kwargs class RpcCommonTestCase(test_utils.BaseTestCase): @@ -139,6 +140,26 @@ class RpcCommonTestCase(test_utils.BaseTestCase): #assure the traceback was added self.assertTrue('raise FakeUserDefinedException' in unicode(after_exc)) + def test_deserialize_remote_exception_args_and_kwargs(self): + """ + Ensure a user defined exception will be supplied the correct args and + kwargs while being deserialized. + """ + self.config(allowed_rpc_exception_modules=[self.__class__.__module__]) + failure = { + 'class': 'FakeUserDefinedException', + 'module': self.__class__.__module__, + 'tb': ['raise FakeUserDefinedException'], + 'args': (u'fakearg',), + 'kwargs': {u'fakekwarg': u'fake'}, + } + serialized = jsonutils.dumps(failure) + + after_exc = rpc_common.deserialize_remote_exception(FLAGS, serialized) + self.assertTrue(isinstance(after_exc, FakeUserDefinedException)) + self.assertEqual(after_exc.args, (u'fakearg',)) + self.assertEqual(after_exc.kwargs, {u'fakekwarg': u'fake'}) + def test_deserialize_remote_exception_cannot_recreate(self): """Ensure a RemoteError is returned on initialization failure. |