[Twisted-Python] how to write a safe catch-all

exarkun at twistedmatrix.com exarkun at twistedmatrix.com
Tue Sep 28 10:21:51 EDT 2010


On 01:48 pm, chris at simplistix.co.uk wrote:
>Hi All,
>
>The attached .py file demonstrates a problem I'm having with a little 
>scheduler I need to maintain.
>
>The loop() function is supposed to be a "catch all and report" error 
>handler. However, when the async code initiated by doStuff throws the 
>AttributeError, what actually gets logged is:
>
>2010-09-28 14:41:15,706 ERROR   : log         (14757|7f691ba676e0): 
>Unhandled Error
>   File "test_looping.py", line 24, in __call__
>     del self.connector
>exceptions.AttributeError: Break instance has no attribute 'connector'
>
>2010-09-28 14:41:15,707 ERROR   : log         (14757|7f691ba676e0): 
>Unhandled scheduled exception
>   File "test_looping.py", line 35, in loop
>     yield doStuff()
>exceptions.GeneratorExit:
>
>But, more crucially, the looping call then appears to stop.

The function you're looping over returns a Deferred that never fires. 
The LoopingCall isn't stopped, it's waiting for the Deferred.
>What can I do to get the exception logged and then everything handled 
>sanely such that the looping call can continue and my lopp function 
>will keep getting called once every second rather than stopping?

When you do reactor.callLater(n, f), you put f into an execution context 
where the only thing that will happen to exceptions it raises is that 
they will be logged.  If you want something else to happen to the 
exception, then you have to arrange for that.  You can do this by 
wrapping f with another function that handles the exception and sends it 
where you want.  Or you can use twisted.internet.task.deferLater, which 
probably does something pretty close to what you want.

Jean-Paul



More information about the Twisted-Python mailing list