[Twisted-Python] xmlrpc doesn't catch XML parsing exceptions

Andrew Dalke dalke at dalkescientific.com
Mon Jun 2 23:05:27 MDT 2003


I used the Twisted code to connect to a URI which wasn't providing 
XML-RPC
services but is providing HTML.  The XML-RPC code tried to parse the
HTML response, and failed.  It reported the failure correctly, but also
spewed a traceback to stdout.  Here's what stdout looks like


Traceback (most recent call last):
   File "E:\Python22\Lib\site-packages\twisted\internet\default.py", 
line 473, in
  doSelect
     _logrun(selectable, _drdw, selectable, method, dict)
   File "E:\Python22\Lib\site-packages\twisted\python\log.py", line 64, 
in callWi
thLogger
     callWithContext({"system": lp}, func, *args, **kw)
   File "E:\Python22\Lib\site-packages\twisted\python\log.py", line 51, 
in callWi
thContext
     return context.call({ILogContext: newCtx}, func, *args, **kw)
   File "E:\Python22\Lib\site-packages\twisted\python\context.py", line 
32, in ca
llWithContext
     return func(*args,**kw)
--- <exception caught here> ---
   File "E:\Python22\Lib\site-packages\twisted\internet\default.py", 
line 482, in
  _doReadOrWrite
     why = getattr(selectable, method)()
   File "E:\Python22\Lib\site-packages\twisted\internet\tcp.py", line 
219, in doR
ead
     return self.protocol.dataReceived(data)
   File "E:\Python22\Lib\site-packages\twisted\protocols\basic.py", line 
179, in
dataReceived
     return self.rawDataReceived(data)
   File "E:\Python22\Lib\site-packages\twisted\protocols\http.py", line 
341, in r
awDataReceived
     self.handleResponseEnd()
   File "E:\Python22\Lib\site-packages\twisted\protocols\http.py", line 
323, in h
andleResponseEnd
     self.handleResponse(b)
   File "E:\Python22\Lib\site-packages\twisted\web\xmlrpc.py", line 174, 
in handl
eResponse
     self.factory.parseResponse(contents)
   File "E:\Python22\Lib\site-packages\twisted\web\xmlrpc.py", line 199, 
in parse
Response
     response = xmlrpclib.loads(contents)
   File "E:\Python22\lib\xmlrpclib.py", line 804, in loads
     p.feed(data)
   File "E:\Python22\lib\xmlrpclib.py", line 390, in feed
     self._parser.Parse(data, 0)
xml.parsers.expat.ExpatError: mismatched tag: line 10, column

The reason is twisted.web.xmlrpc, which has

     def parseResponse(self, contents):
         if not self.deferred:
             return
         try:
             response = xmlrpclib.loads(contents)
         except xmlrpclib.Fault, error:
             self.deferred.errback(error)
             self.deferred = None
         else:
             self.deferred.callback(response[0][0])
             self.deferred = None

There's nothing which handles an XML parsing error.

I don't know who to blame here.  I would like a

         except "XML parsing error", error:

here as well, but there's no way to spell that.  The xmlrpclib code 
chooses
the fastest parser available, and the different parsers could throw 
different
exceptions.  Eg, the Expat parser throws an ExpatError, which is derived
directly from Exception, and shares no other base class with

The best I can think of now is to catch anything which isn't a "normal"
Python exception, that is

         except (StandardError, SystemExit, StopIteration):
             raise
         except (xmlrpclib.Fault, Exception), error:
             self.deferred.errback(error)

(could also use a bare except, but I think that's overkill for this 
case.)
Even that's not perfect.  xmllib.Error is derived from RuntimeError(!).
OTOH, that module is deprecated ....

Oh! Since Fault is derived from exception, could just catch Exception
instead of the 2-ple I have there.

Let me point out that Twisted did a good job of catching the error at a 
higher
level and correctly sending it to my handler, so even if this had 
occurred in
production code the app would have kept working as expected.  This is 
good.

					Andrew
					dalke at dalkescientific.com





More information about the Twisted-Python mailing list