3 from foolscap.api import Violation
5 class ServerFailure(exceptions.Exception):
6 # If the server returns a Failure instead of the normal response to a
7 # protocol, then this exception will be raised, with the Failure that the
8 # server returned as its .remote_failure attribute.
9 def __init__(self, remote_failure):
10 self.remote_failure = remote_failure
12 return repr(self.remote_failure)
14 return str(self.remote_failure)
17 if isinstance(f.value, ServerFailure):
22 return not is_remote(f)
24 def check_remote(f, *errorTypes):
26 return f.value.remote_failure.check(*errorTypes)
29 def check_local(f, *errorTypes):
31 return f.check(*errorTypes)
34 def trap_remote(f, *errorTypes):
36 return f.value.remote_failure.trap(*errorTypes)
39 def trap_local(f, *errorTypes):
41 return f.trap(*errorTypes)
44 def _wrap_server_failure(f):
45 raise ServerFailure(f)
47 class WrappedRemoteReference(object):
48 """I intercept any errback from the server and wrap it in a
51 def __init__(self, original):
54 def callRemote(self, *args, **kwargs):
55 d = self.rref.callRemote(*args, **kwargs)
56 d.addErrback(_wrap_server_failure)
59 def callRemoteOnly(self, *args, **kwargs):
60 return self.rref.callRemoteOnly(*args, **kwargs)
62 def notifyOnDisconnect(self, *args, **kwargs):
63 return self.rref.notifyOnDisconnect(*args, **kwargs)
65 def dontNotifyOnDisconnect(self, *args, **kwargs):
66 return self.rref.dontNotifyOnDisconnect(*args, **kwargs)
68 class VersionedRemoteReference(WrappedRemoteReference):
69 """I wrap a RemoteReference, and add a .version attribute. I also
70 intercept any errback from the server and wrap it in a ServerFailure."""
72 def __init__(self, original, version):
73 WrappedRemoteReference.__init__(self, original)
74 self.version = version
76 def get_versioned_remote_reference(rref, default):
77 """I return a Deferred that fires with a VersionedRemoteReference"""
78 d = rref.callRemote("get_version")
79 def _no_get_version(f):
80 f.trap(Violation, AttributeError)
82 d.addErrback(_no_get_version)
83 def _got_version(version):
84 return VersionedRemoteReference(rref, version)
85 d.addCallback(_got_version)