3 from foolscap.tokens import Violation
5 class ServerFailure(exceptions.Exception):
6 # If the server returns a Failure instead of the normal response to a protocol, then this
7 # exception will be raised, with the Failure that the server returned as its .remote_failure
9 def __init__(self, remote_failure):
10 self.remote_failure = remote_failure
12 return repr(self.remote_failure)
14 return str(self.remote_failure)
16 def _wrap_server_failure(f):
17 raise ServerFailure(f)
19 class WrappedRemoteReference(object):
20 """I intercept any errback from the server and wrap it in a ServerFailure."""
22 def __init__(self, original):
25 def callRemote(self, *args, **kwargs):
26 d = self.rref.callRemote(*args, **kwargs)
27 d.addErrback(_wrap_server_failure)
30 def callRemoteOnly(self, *args, **kwargs):
31 return self.rref.callRemoteOnly(*args, **kwargs)
33 def notifyOnDisconnect(self, *args, **kwargs):
34 return self.rref.notifyOnDisconnect(*args, **kwargs)
36 def dontNotifyOnDisconnect(self, *args, **kwargs):
37 return self.rref.dontNotifyOnDisconnect(*args, **kwargs)
39 class VersionedRemoteReference(WrappedRemoteReference):
40 """I wrap a RemoteReference, and add a .version attribute. I also intercept any errback from
41 the server and wrap it in a ServerFailure."""
43 def __init__(self, original, version):
44 WrappedRemoteReference.__init__(self, original)
45 self.version = version
47 def get_versioned_remote_reference(rref, default):
48 """I return a Deferred that fires with a VersionedRemoteReference"""
49 d = rref.callRemote("get_version")
50 def _no_get_version(f):
51 f.trap(Violation, AttributeError)
53 d.addErrback(_no_get_version)
54 def _got_version(version):
55 return VersionedRemoteReference(rref, version)
56 d.addCallback(_got_version)