#!/usr/bin/env python # Copyright (c) Twisted Matrix Laboratories. # See LICENSE for details. from __future__ import print_function from twisted.spread import pb, jelly from twisted.python import log from twisted.internet import reactor class MyException(pb.Error): pass class MyOtherException(pb.Error): pass class ScaryObject: # not safe for serialization pass def worksLike(obj): # the callback/errback sequence in class One works just like an # asynchronous version of the following: try: response = obj.callMethod(name, arg) except pb.DeadReferenceError: print(" stale reference: the client disconnected or crashed") except jelly.InsecureJelly: print(" InsecureJelly: you tried to send something unsafe to them") except (MyException, MyOtherException): print(" remote raised a MyException") # or MyOtherException except: print(" something else happened") else: print(" method successful, response:", response) class One: def worked(self, response): print(" method successful, response:", response) def check_InsecureJelly(self, failure): failure.trap(jelly.InsecureJelly) print(" InsecureJelly: you tried to send something unsafe to them") return None def check_MyException(self, failure): which = failure.trap(MyException, MyOtherException) if which == MyException: print(" remote raised a MyException") else: print(" remote raised a MyOtherException") return None def catch_everythingElse(self, failure): print(" something else happened") log.err(failure) return None def doCall(self, explanation, arg): print(explanation) try: deferred = self.remote.callRemote("fooMethod", arg) deferred.addCallback(self.worked) deferred.addErrback(self.check_InsecureJelly) deferred.addErrback(self.check_MyException) deferred.addErrback(self.catch_everythingElse) except pb.DeadReferenceError: print(" stale reference: the client disconnected or crashed") def callOne(self): self.doCall("callOne: call with safe object", "safe string") def callTwo(self): self.doCall("callTwo: call with dangerous object", ScaryObject()) def callThree(self): self.doCall("callThree: call that raises remote exception", "panic!") def callShutdown(self): print("telling them to shut down") self.remote.callRemote("shutdown") def callFour(self): self.doCall("callFour: call on stale reference", "dummy") def got_obj(self, obj): self.remote = obj reactor.callLater(1, self.callOne) reactor.callLater(2, self.callTwo) reactor.callLater(3, self.callThree) reactor.callLater(4, self.callShutdown) reactor.callLater(5, self.callFour) reactor.callLater(6, reactor.stop) factory = pb.PBClientFactory() reactor.connectTCP("localhost", 8800, factory) deferred = factory.getRootObject() deferred.addCallback(One().got_obj) reactor.run()