Reputation: 1660
I have a problem figuring out a somewhat simple twisted python code. From what I have red in the docs, the code here should work without Unhandled Error.
I get this:
HELLO!
HANDLED!
HANDLED 2!
Unhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
File "package_tester.py", line 31, in <module>
a().callback(2)
File "/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py", line 368, in callback
self._startRunCallbacks(result)
File "/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py", line 464, in _startRunCallbacks
self._runCallbacks()
--- <exception caught here> ---
File "/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py", line 551, in _runCallbacks
current.result = callback(current.result, *args, **kw)
File "package_tester.py", line 5, in c
raise Exception()
exceptions.Exception:
Isn't the failure from the chained deferred passed to end() errback ?
For some reason I can't comment below Bula's post
I managed to bypass the behaviour of 'unexpected1.py' by simply adding
@defer.inlineCallbacks
def sync_deferred(self, result, deferred):
"""
Wait for a deferred to end before continuing.
@param deferred: deferred which will be waited to finish so the chain
can continue.
@return: result from the deferred.
"""
r = yield deferred
defer.returnValue(r)
sync_deferred after every chainDeferred, in which the result from a child deferred needs to be "waited" so the parent can continue with this result.
Upvotes: 1
Views: 2738
Reputation: 1586
In this excellent post there are few examples of potential problems that can arise when using chainDeferred
. So when using this method one should be careful.
Upvotes: 1
Reputation: 48335
From the documentation of Deferred.chainDeferred
:
When you chain a deferred d2 to another deferred d1 with d1.chainDeferred(d2),
you are making d2 participate in the callback chain of d1. Thus any event that
fires d1 will also fire d2.
The error you supply to d1
(d
in your example code) is passed on to d2
(l
in your example code). This means that d2
/l
ends up with an error, which is passed to its first and only errback, new_f
. new_f
returns its argument, leaving d2
/l
with an error result, which is not handled.
If you meant new_f
to handle the failure, then you should make it ''not'' return a failure. From the Deferred
howto:
If the errback does returns a Failure or raise an exception, then that is passed
to the next errback, and so on.
Upvotes: 1