[Twisted-Python] Catching all the exceptions in a Twisted program
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]. Specifically, when the exception was inside a deferred, it didn't call excepthook. 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? 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. 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/
On 10:57 am, facundobatista@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@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
On Mon, Oct 25, 2010 at 9:29 AM, <exarkun@twistedmatrix.com> wrote:
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
Thanks Jean-Paul! Regards, -- . Facundo Blog: http://www.taniquetil.com.ar/plog/ PyAr: http://www.python.org/ar/
participants (2)
-
exarkun@twistedmatrix.com
-
Facundo Batista