[Twisted-Python] Catching all the exceptions in a Twisted program

exarkun at twistedmatrix.com exarkun at twistedmatrix.com
Mon Oct 25 08:29:58 EDT 2010

On 10:57 am, facundobatista at gmail.com wrote:
>I've just subscribed to the list, but I'm using Twisted from a while 
>I need to do something, and wasn't able to find out how to do it. 
>Well, I
>*did* find out, but it's a horrible hack, and actually depends on 
>that may be a bug, so it's worth asking here about this :)
>In a project I'm doing [0], I want to catch all problems (unhandled
>exceptions), log them and show them in stderr after a bit massaging. 
>first approach was to hook me in sys.excepthook, and it worked on some
>cases.  But I saw some cases where it didn't [1].

Right.  Instead of letting any exception from application code abort the 
process entirely, most places in Twisted catch and log unexpected 
>Specifically, when the exception was inside a deferred, it didn't call

Another case where this will happen is if a protocol's dataReceived 
method raises an exception.  Or if a function passed to 
reactor.callLater raises an exception.
>Why not? I started to check the code, and found the following
>snippet, at the end of Deferred._run_callbacks, in defer.py:
>   if isinstance(self.result, failure.Failure):
>       self.result.cleanFailure()
>       if self._debugInfo is None:
>           self._debugInfo = DebugInfo()
>       self._debugInfo.failResult = self.result
>> From this, I have two questions:
>1. The rest of the code only instantiates and uses DebugInfo
>   "if self.debug".  Why this part of the code doesn't care about the
>   self.debug flag and always uses it?  Is it intended and DebugInfo()
>   not being used for debug is a misname left there for historical
>   reasons?  Should I open a bug about this?

It's correct as is.  DebugInfo is used for a few things.  Tracking 
unhandled errors is one of them, and it is always enabled, whether 
"Deferred debugging" is on or not.
>2. I did the following (ugly) hack to achieve my results:
>    import twisted.internet.defer
>    # ugliest thing I saw in a *long* time
>    class MyDebugInfo(object):
>        def _error_happened(self, failure):
>            msg = failure.getTraceback()
>            _expose_exception(msg)
>        failResult = property(fset=_error_happened)
>    twisted.internet.defer.DebugInfo = MyDebugInfo
>   Is there a better way to do this?  Actually, this is working 
>   but I don't know if it's the right way to do it, and don't want to
>   depend of DebugInfo() being called always in this case.

You should add a log observer that watches for errors.


>Thank you very much!
>[0] http://launchpad.net/magicicada
>[1] http://bugs.launchpad.net/magicicada/+bug/665681
>.    Facundo
>Blog: http://www.taniquetil.com.ar/plog/
>PyAr: http://www.python.org/ar/
>Twisted-Python mailing list
>Twisted-Python at twistedmatrix.com

More information about the Twisted-Python mailing list