How to catch exceptions from a twisted inlineCallbacks decorated function?

Viewed 2263

I am getting started with twisted as one of the libs I'll be using depends on it. In an early test I am confused about how to catch an exception thrown in a function like this:

@defer.inlineCallbacks
def read_input_status(self, address, length, callback):
    assert callback
    # ...

If callbackis None an AssertionError is thrown, so I tried to see it... The function is called like this:

def cb():
    pass
def eb():
    pass

d = task.deferLater(reactor, 1, client.read_input_status, 0x0000, 8, None)
d.addCallback(cb)
d.addErrback(eb)

I'm calling deferLater here on purpose to be able to deal with errors, as I understood that's not possible when using `callLater'. But my errback is never called.

What's weird is that when trying to debug and looking at the twisted lib's code I think I've seen a reason, why my errback is without effect. My decorated generator function (argument g below) is called by twisted's defer._inlineCallbacks implementation like this (breviated):

def _inlineCallbacks(result, g, deferred):
    # ...
    while 1:
        try:
            # ...
            result = g.send(result)
        except:
            deferred.errback()
            return deferred

I do see my exception pop up in the last section, where a deferred's errback is then called. But: that is not my deferred... If I go up one call in the debugger's call hierarchy, I see which deferred object is actually passed to _inlineCallbacks:

def unwindGenerator(*args, **kwargs):
    # ...
    return _inlineCallbacks(None, gen, Deferred())

Am I mistaken or is this simply a new object, empty, plain, without an callbacks/errbacks attached?

Sorry for this lengthy elaboration. Couldn't find anything immediately related, except for this SO post where I could not directly see how it solves my issue.

Thanks a lot.

[UPDATE] Please see this gist for working sample code (Python 2.7.6, Twisted 13.2.0).

1 Answers
Related