Search code examples
pythonmultithreadingsimplexmlrpcserverxmlrpclibxmlrpcclient

How to see traceback on xmlrpc server, not client?


I have simple xmlrpc server code:

from SimpleXMLRPCServer import SimpleXMLRPCServer

port = 9999

def func():
    print 'Hi!'
    print x # error!
    print 'Bye!'

if __name__ == '__main__':
    server = SimpleXMLRPCServer(("localhost", port))
    print "Listening on port %s..." % port
    server.register_function(func)
    server.serve_forever()

Sample session.

Client:

>>> import xmlrpclib
>>> p = xmlrpclib.ServerProxy('http://localhost:9999')
>>> p.func()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python26\lib\xmlrpclib.py", line 1199, in __call__
    return self.__send(self.__name, args)
  File "C:\Python26\lib\xmlrpclib.py", line 1489, in __request
    verbose=self.__verbose
  File "C:\Python26\lib\xmlrpclib.py", line 1253, in request
    return self._parse_response(h.getfile(), sock)
  File "C:\Python26\lib\xmlrpclib.py", line 1392, in _parse_response
    return u.close()
  File "C:\Python26\lib\xmlrpclib.py", line 838, in close
    raise Fault(**self._stack[0])
xmlrpclib.Fault: <Fault 1: "<type 'exceptions.NameError'>:global name 'x' is not defined">
>>>

Server:

Listening on port 9999...
Hi!
localhost - - [11/Jan/2011 16:17:09] "POST /RPC2 HTTP/1.0" 200 -

The question is if I can get this trace back also on server. I need to know if something went wrong with processing query. I'm not using client written in Python so it is hard for me to get traceback like above.


Solution

  • You can do something like this:

    from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
    
    port = 9999
    
    def func():
        print 'Hi!'
        print x # error!
        print 'Bye!'
    
    class Handler(SimpleXMLRPCRequestHandler):
         def _dispatch(self, method, params):
             try: 
                 return self.server.funcs[method](*params)
             except:
                 import traceback
                 traceback.print_exc()
                 raise
    
    
    if __name__ == '__main__':
        server = SimpleXMLRPCServer(("localhost", port), Handler)
        server.register_function(func)
        print "Listening on port %s..." % port
        server.serve_forever()
    

    Traceback server side:

    Listening on port 9999...
    Hi!
    Traceback (most recent call last):
      File "xml.py", line 13, in _dispatch
        value = self.server.funcs[method](*params)
      File "xml.py", line 7, in func
        print x # error!
    NameError: global name 'x' is not defined
    localhost - - [11/Jan/2011 17:13:16] "POST /RPC2 HTTP/1.0" 200