[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:
>Hello!
>
>I've just subscribed to the list, but I'm using Twisted from a while 
>ago.
>
>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 
>something
>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. 
>My
>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 
exceptions.
>Specifically, when the exception was inside a deferred, it didn't call
>excepthook.

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 
>correctly,
>   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.

http://twistedmatrix.com/documents/9.0.0/core/howto/logging.html

Jean-Paul
>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
>http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python



More information about the Twisted-Python mailing list