[Twisted-Python] Understanding deferred and error handling

Phil Mayers p.mayers at imperial.ac.uk
Wed Apr 20 11:31:23 MDT 2011


On 04/20/2011 05:28 AM, David wrote:
> Hi,
>
> I have a hard time figuring out error handling with deferred in twisted.
> More exactly, I don't understand how to always get meaningful tracebacks
> to understand where the error actually happened. For a simple example:
>
> import sys
>
> import twisted.web.client
>
> from twisted.internet import defer
> from twisted.internet import reactor
> from twisted.python import log
>
> def remote_call():
>       # No process bound to 8083 ->  connection refused
>       d = twisted.web.client.getPage("http://localhost:8083")
>       return d
>
> def main():
>       d = remote_call()
>       def _stop(arg):
>           reactor.stop()
>       d.addBoth(_stop)
>
> log.startLogging(sys.stdout)
> reactor.callWhenRunning(main)
> reactor.run()
>
> This will simply print no error in the log:
>
> 2011-04-20 12:37:40+0900 [-] Log opened.
> 2011-04-20 12:37:40+0900 [-] Starting factory<HTTPClientFactory:
> http://localhost:8083>
> 2011-04-20 12:37:40+0900 [HTTPPageGetter,client] Stopping factory
> <HTTPClientFactory: http://localhost:8083>
> 2011-04-20 12:37:40+0900 [-] Main loop terminated.
>
> This already bothers me at a fundamental level, because it means it is
> very easy to "swallow" errors without being aware of it. Is there a
> "systematic" solution to this issue, or am I condemned to handle errors
> systematically everywhere in my code ?
>
> Now, if I add an errback for logging purpose:
>
> def main():
>       d = remote_call()
>       def _stop(arg):
>           reactor.stop()
>       d.addErrback(log.err)
>       d.addBoth(_stop)
>
> I get something like:
>
> 2011-04-20 12:38:35+0900 [-] Log opened.
> 2011-04-20 12:38:35+0900 [-] Starting factory<HTTPClientFactory:
> http://localhost:8083>
> 2011-04-20 12:38:35+0900 [HTTPPageGetter,client] Unhandled Error
> 	Traceback (most recent call last):
> 	Failure: twisted.web.error.Error: 404 Not Found
> 	
> 2011-04-20 12:38:35+0900 [HTTPPageGetter,client] Stopping factory
> <HTTPClientFactory: http://localhost:8083>
> 2011-04-20 12:38:35+0900 [-] Main loop terminated.
>
> I do get an error, but I don't get a traceback. Interestingly enough, if
> I use printTraceback:
>
> def main():
>       d = remote_call()
>       def _stop(arg):
>           reactor.stop()
>       def log_error(failure):
>           log.err(failure.printTraceback())
>           return failure
>       d.addErrback(log_error)
>       d.addBoth(_stop)
>
> I don't get any traceback either.

As other people have pointed out, you're discarding the failure.

This:

def on_error(failure):
     return
d = some_call()
d.addErrback(on_error)

...is equivalent to synchronous code of the form:

try:
   some_call()
except:
   pass

...i.e. silently eating all exceptions. The latter is usually bad 
python, and so the former is usually bad Twisted ;o)







More information about the Twisted-Python mailing list