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

Paul Goins general at vultaire.net
Mon Feb 22 00:03:12 MST 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?

Thanks.

- 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):

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

    @defer.inlineCallbacks
    def _do_something_else(self):
        yield
        raise Exception("die die die!!!")

@defer.inlineCallbacks
def cause_trouble(app):
    val = yield app.xmlrpc_dosomething()
    print val
    reactor.stop()

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)
    reactor.run()






More information about the Twisted-Python mailing list