[Twisted-Python] Understanding deferred and error handling

Tristan Seligmann mithrandi at mithrandi.net
Wed Apr 20 06:44:12 EDT 2011


On Wed, Apr 20, 2011 at 12:15 PM, Jason Rennie <jrennie at gmail.com> wrote:
>>
>>     def log_error(failure):
>>
>>         log.err(failure.printTraceback())
>>         return failure
>>     d.addErrback(log_error)
>>     d.addBoth(_stop)
>
> Use d.addCallbacks(_stop, log_error) instead of addBoth/addErrback.  Also,
> you probably want "log.err(failure.getTraceback())" instead of
> "log.err(failure.printTraceback())".  printTraceback does not return a
> meaningful value IIUC.

Actually, you just want:

    log.err(failure)

I don't think there's anything particularly wrong with using
addErrback / addBoth in that way, either. If there is an error, you
want to log it; and then regardless of whether there was an error or
not, and whether the attempt to log the error failed, you want to stop
the reactor; this is exactly what the addErrback/addBoth code achieves
in this case. The equivalent synchronous code looks something like:

try:
    remote_call()
except:
    logTheError()
finally:
    reactor.stop()

The reason you don't get a traceback in this case is that there isn't
one; the exception is created directly as a result of parsing the
response from the HTTP server, instead of being thrown in code lower
down the stack and caught higher up. Unfortunately this situation is
quite common in asynchronous code; there is no direct equivalent of a
"stack trace" for asynchronous code, so often you have a Failure that
carries no indication of where the operation that failed was
initiated, although turning on Deferred debugging (see
Deferred.setDebugging) can sometimes be helpful in these situations.
-- 
mithrandi, i Ainil en-Balandor, a faer Ambar



More information about the Twisted-Python mailing list