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 callback
is 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).
Figured it out after rereading the docs about Twisted Deferred callbacks and errbacks. The issue with the code above and in the linked gist are the missing arguments for callback and errback. If I replace what's written above with the following code, the exception is caught fine and notified via errback as expected:
def cb(result):
pass
def eb(failure):
pass
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With