[Twisted-Python] Try/catching yielded Exceptions and getting proper tracebacks

Paul Goins general at vultaire.net
Mon Feb 22 02:03:12 EST 2010

I'm frequently using the inlineCallbacks idiom for writing code, but am
often finding myself frustrated with rather counterintuitive tracebacks.

Let's say I'm writing an XML-RPC handler, and even if an exception
occurs, I want it to return something to the user and dump the exception
to the log file.  However, if an exception occurs when I'm using the
inlineCallbacks decorator, I sometimes get lacking tracebacks.  Maybe
I'll have the line number of the function that yielded the exception,
but I'll have no detailed information as to where the exception really
came from.

For example, in the example I've pasted at the end of this mail, I get a
traceback as follows:

Traceback (most recent call last):
  File "exceptions.py", line 13, in xmlrpc_dosomething
    result = yield self._do_something_else()
Exception: die die die!!!

However, the exception happens within _do_something_else on line 20.

I have a simple complete example copy/pasted below.  Is there a better
way to accomplish this?


- Paul Goins

from twisted.web.xmlrpc import XMLRPC
from twisted.web.server import Site
from twisted.web.resource import Resource
from twisted.internet import reactor, defer
import sys, traceback

class MyApp(XMLRPC):

    def xmlrpc_dosomething(self):
            result = yield self._do_something_else()
        except Exception:
            print >> sys.stderr, traceback.format_exc()

    def _do_something_else(self):
        raise Exception("die die die!!!")

def cause_trouble(app):
    val = yield app.xmlrpc_dosomething()
    print val

if __name__ == "__main__":
    app = MyApp()
    r = Resource()
    r.putChild("RPC2", app)
    s = Site(r)
    reactor.listenTCP(8123, s)
    reactor.callLater(0.2, cause_trouble, app)

More information about the Twisted-Python mailing list