summaryrefslogtreecommitdiffstats
path: root/nova/rpc.py
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@gmail.com>2010-08-12 21:27:53 -0700
committerVishvananda Ishaya <vishvananda@gmail.com>2010-08-12 21:27:53 -0700
commita679cab031ec91dd719b9ba887cdae4f595b2ca4 (patch)
treecbc8b1772582f3f8b5ab5694147580e416e0fd68 /nova/rpc.py
parent2bbb2b86272c89b35a1042ab2866bbe4863bc3e3 (diff)
downloadnova-a679cab031ec91dd719b9ba887cdae4f595b2ca4.tar.gz
nova-a679cab031ec91dd719b9ba887cdae4f595b2ca4.tar.xz
nova-a679cab031ec91dd719b9ba887cdae4f595b2ca4.zip
make rpc.call propogate exception info. Includes tests
Diffstat (limited to 'nova/rpc.py')
-rw-r--r--nova/rpc.py38
1 files changed, 29 insertions, 9 deletions
diff --git a/nova/rpc.py b/nova/rpc.py
index 2a550c3ae..e06a3e19b 100644
--- a/nova/rpc.py
+++ b/nova/rpc.py
@@ -40,7 +40,7 @@ FLAGS = flags.FLAGS
_log = logging.getLogger('amqplib')
-_log.setLevel(logging.WARN)
+_log.setLevel(logging.DEBUG)
class Connection(connection.BrokerConnection):
@@ -141,8 +141,8 @@ class AdapterConsumer(TopicConsumer):
node_args = dict((str(k), v) for k, v in args.iteritems())
d = defer.maybeDeferred(node_func, **node_args)
if msg_id:
- d.addCallback(lambda rval: msg_reply(msg_id, rval))
- d.addErrback(lambda e: msg_reply(msg_id, str(e)))
+ d.addCallback(lambda rval: msg_reply(msg_id, rval, None))
+ d.addErrback(lambda e: msg_reply(msg_id, None, e))
return
@@ -174,20 +174,37 @@ class DirectPublisher(Publisher):
super(DirectPublisher, self).__init__(connection=connection)
-def msg_reply(msg_id, reply):
+def msg_reply(msg_id, reply=None, failure=None):
+ if failure:
+ message = failure.getErrorMessage()
+ traceback = failure.getTraceback()
+ logging.error("Returning exception %s to caller", message)
+ logging.error(traceback)
+ failure = (failure.type.__name__, str(failure.value), traceback)
conn = Connection.instance()
publisher = DirectPublisher(connection=conn, msg_id=msg_id)
-
try:
- publisher.send({'result': reply})
- except TypeError:
+ publisher.send({'result': reply, 'failure': failure})
+ except Exception, exc:
publisher.send(
{'result': dict((k, repr(v))
- for k, v in reply.__dict__.iteritems())
+ for k, v in reply.__dict__.iteritems()),
+ 'failure': failure
})
publisher.close()
+class RemoteError(exception.Error):
+ """signifies that a remote class has raised an exception"""
+ def __init__(self, type, value, traceback):
+ self.type = type
+ self.value = value
+ self.traceback = traceback
+ super(RemoteError, self).__init__("%s %s\n%s" % (type,
+ value,
+ traceback))
+
+
def call(topic, msg):
_log.debug("Making asynchronous call...")
msg_id = uuid.uuid4().hex
@@ -199,7 +216,10 @@ def call(topic, msg):
consumer = DirectConsumer(connection=conn, msg_id=msg_id)
def deferred_receive(data, message):
message.ack()
- d.callback(data)
+ if data['failure']:
+ return d.errback(RemoteError(*data['failure']))
+ else:
+ return d.callback(data['result'])
consumer.register_callback(deferred_receive)
injected = consumer.attach_to_tornado()