Re: [Twisted-Python] understanding deferreds
![](https://secure.gravatar.com/avatar/c8f4d4d1a8fc53c13ed05c202e0257fe.jpg?s=120&d=mm&r=g)
"Michael" == Michael P Soulier <msoulier@digitaltorque.ca> writes:
Michael> I'm a bit confused as to the "visual explanation". It seems like Michael> if you have a single callback and errback, that if the errback Michael> wants to swallow the error, the callback will not be called at Michael> all, since deferred processing will look for the second callback Michael> at that point by the diagram. Michael> So, right now I'm calling my own callback from the errback if I Michael> want to swallow the error. Is there a better way? Yes. Add the errback to the deferred and then add the callback. d = somethingReturningADeferred() d.addErrback(cleanup) d.addCallback(dealWithResult) If cleanup doesn't return the failure object it's passed or raise some an exception, processing will pass to dealWithResult. Note that dealWithResult will get as an argument whatever cleanup returns (that means None if cleanup doesn't explicitly return something). You're thinking about this in the right way. Understanding the difference between the above and d = somethingReturningADeferred() d.addCallbacks(dealWithResult, cleanup) is important. Terry
![](https://secure.gravatar.com/avatar/65c36b5d87780b4975009efd546ac1a9.jpg?s=120&d=mm&r=g)
On Thu, Jan 28, 2010 at 05:46:08PM -0500, Terry Jones wrote:
Is it true, that adding many callback functions as filters is elegant, but impractical solution? Since there is only a [linear] list of pairs (callback, errback), the last errbacks have to be complex to distinguish the failures, that came from the previous callback from failures, that traverse the errback chain from the beginning. Should I only use errbacks as a means of catching errors only from who have produced the Deferred? And never use them to catch errors, that came from my callbacks? Nevertheless the Deferred mechanism always catch the exceptions in my callbacks, I have to always catch them myself and never let them out uncontrolled (since I cannot distinguish, say TypeError that came from the first callback from TypeError, that came from the next callback, and they are not the same for me, since I try to do a cleanup)? But then I have to translate all errors to my invented exceptions, so they will differ. Or may I pause() a Deferred in a errback, after I have processed the error and want no error propagation any further? If I can pause(), what can I do if my code is not the final consumer of the Deferred's result, but lives in the middle of the processing chain and have to pass the signal, that there will be no further result, so the consumer will do appropriately? Maybe we need graph of callbacks (or just tree)? Or, said in other words, groups of callbacks (to be able to exit the processing of the current group on some failures)? Or just tell me, that I have missed something, I'm still getting into the theme! Thanks!
-- Alexey S
![](https://secure.gravatar.com/avatar/977ce87331ed639b45834f25e766688b.jpg?s=120&d=mm&r=g)
twisted-web@udmvt.ru wrote: [...]
This is no different to regular Python code, which has a linear call stack which can have exception handlers at any point on the stack. The exact same tradeoffs apply about which exceptions to raise and which to catch, and at what points. -Andrew.
![](https://secure.gravatar.com/avatar/f48cdf7f95adb87034f78f44d46cc785.jpg?s=120&d=mm&r=g)
On Sat, Jan 30, 2010 at 2:16 AM, Andrew Bennetts <andrew@bemusement.org> wrote:
In normal python code you might put each filter into a try/except block, wouldn't this be equivalent to putting a callback and errback (addCallbacks) each time you are adding a callback. So that the errback would then know which callback (the previous one) failed.
![](https://secure.gravatar.com/avatar/977ce87331ed639b45834f25e766688b.jpg?s=120&d=mm&r=g)
Landreville wrote:
Yes and no. Yes, you could use addCallbacks as you suggest to get a clearer idea of where an exception was raised from, and that approach certainly suits some code. But unless your Python code usually uses bare excepts (“except:” rather than “except SpecifcException:”), which is generally bad style, you can't be sure without horrible introspection where precisely in the code the exception was raised from. But then, you generally don't need to know... e.g. it rarely matters where a KeyboardInterrupt happened, you probably will always want to respond to it the same way. Again, to mind at least, the tradeoffs of bare excepts vs. specific exception handlers have very direct parallels with Deferred callback/errback chains. Ditto for how much code should be inside a “try” block, etc. They are just exception handlers for async code, the way you should deal with exceptions might be spelled rather differently but the principles are the same. -Andrew.
![](https://secure.gravatar.com/avatar/65c36b5d87780b4975009efd546ac1a9.jpg?s=120&d=mm&r=g)
On Thu, Jan 28, 2010 at 05:46:08PM -0500, Terry Jones wrote:
Is it true, that adding many callback functions as filters is elegant, but impractical solution? Since there is only a [linear] list of pairs (callback, errback), the last errbacks have to be complex to distinguish the failures, that came from the previous callback from failures, that traverse the errback chain from the beginning. Should I only use errbacks as a means of catching errors only from who have produced the Deferred? And never use them to catch errors, that came from my callbacks? Nevertheless the Deferred mechanism always catch the exceptions in my callbacks, I have to always catch them myself and never let them out uncontrolled (since I cannot distinguish, say TypeError that came from the first callback from TypeError, that came from the next callback, and they are not the same for me, since I try to do a cleanup)? But then I have to translate all errors to my invented exceptions, so they will differ. Or may I pause() a Deferred in a errback, after I have processed the error and want no error propagation any further? If I can pause(), what can I do if my code is not the final consumer of the Deferred's result, but lives in the middle of the processing chain and have to pass the signal, that there will be no further result, so the consumer will do appropriately? Maybe we need graph of callbacks (or just tree)? Or, said in other words, groups of callbacks (to be able to exit the processing of the current group on some failures)? Or just tell me, that I have missed something, I'm still getting into the theme! Thanks!
-- Alexey S
![](https://secure.gravatar.com/avatar/977ce87331ed639b45834f25e766688b.jpg?s=120&d=mm&r=g)
twisted-web@udmvt.ru wrote: [...]
This is no different to regular Python code, which has a linear call stack which can have exception handlers at any point on the stack. The exact same tradeoffs apply about which exceptions to raise and which to catch, and at what points. -Andrew.
![](https://secure.gravatar.com/avatar/f48cdf7f95adb87034f78f44d46cc785.jpg?s=120&d=mm&r=g)
On Sat, Jan 30, 2010 at 2:16 AM, Andrew Bennetts <andrew@bemusement.org> wrote:
In normal python code you might put each filter into a try/except block, wouldn't this be equivalent to putting a callback and errback (addCallbacks) each time you are adding a callback. So that the errback would then know which callback (the previous one) failed.
![](https://secure.gravatar.com/avatar/977ce87331ed639b45834f25e766688b.jpg?s=120&d=mm&r=g)
Landreville wrote:
Yes and no. Yes, you could use addCallbacks as you suggest to get a clearer idea of where an exception was raised from, and that approach certainly suits some code. But unless your Python code usually uses bare excepts (“except:” rather than “except SpecifcException:”), which is generally bad style, you can't be sure without horrible introspection where precisely in the code the exception was raised from. But then, you generally don't need to know... e.g. it rarely matters where a KeyboardInterrupt happened, you probably will always want to respond to it the same way. Again, to mind at least, the tradeoffs of bare excepts vs. specific exception handlers have very direct parallels with Deferred callback/errback chains. Ditto for how much code should be inside a “try” block, etc. They are just exception handlers for async code, the way you should deal with exceptions might be spelled rather differently but the principles are the same. -Andrew.
participants (4)
-
Andrew Bennetts
-
Landreville
-
Terry Jones
-
twisted-web@udmvt.ru