From 6667c5c3485db2ec1da350d4b90896b871e07bad Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Thu, 14 Feb 2013 10:54:07 +0100 Subject: [PATCH] [2676] Error handling in the rpc_call --- src/lib/python/isc/config/ccsession.py | 29 +++++++++++++++++++ .../python/isc/config/tests/ccsession_test.py | 13 +++++++++ 2 files changed, 42 insertions(+) diff --git a/src/lib/python/isc/config/ccsession.py b/src/lib/python/isc/config/ccsession.py index c5c8a891f0..529408c6a6 100644 --- a/src/lib/python/isc/config/ccsession.py +++ b/src/lib/python/isc/config/ccsession.py @@ -51,6 +51,31 @@ logger = isc.log.Logger("config") class ModuleCCSessionError(Exception): pass +class RPCError(ModuleCCSessionError): + """ + An exception raised by rpc_call in case the remote side reports + an error. It can be used to distinguish remote errors from protocol errors. + Also, it holds the code as well as the error message. + """ + def __init__(self, code, message): + ModuleCCSessionError.__init__(self, message) + self.__code = code + + def code(self): + """ + The code as sent over the CC. + """ + return self.__code + +class RPCRecipientMissing(RPCError): + """ + Special version of the RPCError, for cases the recipient of the call + isn't connected to the bus. The code is always + isc.cc.proto_defs.CC_REPLY_NO_RECPT. + """ + def __init__(self, message): + RPCError.__init__(self, CC_REPLY_NO_RECPT, message) + def parse_answer(msg): """Returns a tuple (rcode, value), where value depends on the command that was called. If rcode != 0, value is a string @@ -484,6 +509,10 @@ class ModuleCCSession(ConfigData): # works) reply, rheaders = self._session.group_recvmsg(nonblock=False, seq=seq) code, value = parse_answer(reply) + if code == CC_REPLY_NO_RECPT: + raise RPCRecipientMissing(value) + elif code != 0: + raise RPCError(code, value) return value class UIModuleCCSession(MultiConfigData): diff --git a/src/lib/python/isc/config/tests/ccsession_test.py b/src/lib/python/isc/config/tests/ccsession_test.py index cdce5bbad9..cc81526fc1 100644 --- a/src/lib/python/isc/config/tests/ccsession_test.py +++ b/src/lib/python/isc/config/tests/ccsession_test.py @@ -335,6 +335,19 @@ class TestModuleCCSession(unittest.TestCase): """ self.assertRaises(ModuleCCSessionError, self.rpc_check, ["Nonsense"]) + def test_rpc_call_error(self): + """ + Test it raises an exception when the remote side reports an error. + """ + self.assertRaises(RPCError, self.rpc_check, {"result": [1, "Error"]}) + + def test_rpc_call_no_recpt(self): + """ + Test RPC raises an error when the recipient is not there. + """ + self.assertRaises(RPCRecipientMissing, self.rpc_check, + {"result": [-1, "Error"]}) + def my_config_handler_ok(self, new_config): return isc.config.ccsession.create_answer(0)