"""xmlrpc Specialized XML-RPC support that can raise exceptions across the client/server boundary. To use this, just create an instance of Server and call methods on it. Special exceptions raised on the server will cause the same exceptions to be triggered on the client side. """ import xmlrpclib import re __all__ = ['Server'] # List of exceptions that are allowed. Only exceptions listed here will be reconstructed # from an xmlrpclib.Fault instance. allowed_errors = [ValueError, TypeError] error_pat = re.compile('(?P[^:]*):(?P.*$)') class ExceptionUnmarshaller (xmlrpclib.Unmarshaller): def close(self): # return response tuple and target method if self._type is None or self._marks: raise xmlrpclib.ResponseError() if self._type == "fault": d = self._stack[0] m = error_pat.match(d['faultString']) if m: exception_name = m.group('exception') rest = m.group('rest') for exc in allowed_errors: if exc.__name__ == exception_name: raise exc(rest) # Fall through and just raise the fault raise xmlrpclib.Fault(**d) return tuple(self._stack) class ExceptionTransport (xmlrpclib.Transport): # Override user-agent if desired ##user_agent = "xmlrpc-exceptions/0.0.1" def getparser (self): # We want to use our own custom unmarshaller unmarshaller = ExceptionUnmarshaller() parser = xmlrpclib.ExpatParser(unmarshaller) return parser, unmarshaller # Alternatively you can just use the regular ServerProxy and pass it # an instance of ExceptionTransport. class Server (xmlrpclib.ServerProxy): def __init__ (self, *args, **kwargs): # Supply our own transport kwargs['transport'] = ExceptionTransport() xmlrpclib.ServerProxy.__init__(self, *args, **kwargs) if __name__ == '__main__': s = Server('http://localhost:8000') print s.exception() # Sample code for a server that returns exceptions in the right format import sys, xmlrpclib from SimpleXMLRPCServer import SimpleXMLRPCServer def exception (): try: # Put code here, call other functions int('a') except Exception, exc: raise xmlrpclib.Fault(1, '%s:%s' % (exc.__class__.__name__, exc) ) server = SimpleXMLRPCServer(("localhost", 8000)) server.register_function(exception) server.serve_forever()