text: 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()