I am developing a basic client/server application based on twisted. For communication purposes I am using perspective broker. I have problems with inlineCallbacks and remotely raised errors:
My client code looks like this (pseudo code):
class Client: @defer.inlineCallbacks def login(self, prms): self.factory = pb.PBClientFactory() reactor.connect(host, port) self.perspective = yield self.factory.login() self.services = yield self.perspective.callRemote('getClientServices')
When using this class in application, I want to handle errors raised remotely:
@defer.inlineCallbacks def main(): client = Client() try: yield client.login(prms) except Exception, e: print 'Handled exception:', e
However, no matter what is raised on remote side, except block is never used. But if I change the code to plain except, exception is handled:
@defer.inlineCallbacks def main(): client = Client() try: client.login(prms) except: print 'Some error occurred'
If I rewrite this function using classic deferred style, it works as excepted (prints error with the correct type):
def eb_failure(failure): print type(failure), failure
def cb_success(result): print 'OK', result
def main(): client = Client() d = client.login(prms) d.addCallbacks(cb_success, eb_failure)
I am purposely raising errors derived from pb.Error. Using the inlineCallbacks version I can only inspect remote errors with sys.exc_info(), and that results in a plain string object, which includes the classname of the original error like 'myerror.MyAuthenticationError'
What am I doing wrong? Is there a way to resolve this?