summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openstack/common/rpc/common.py2
-rw-r--r--tests/unit/rpc/test_common.py25
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.