[Twisted-Python] how to write a safe catch-all
exarkun at twistedmatrix.com
exarkun at twistedmatrix.com
Thu Sep 30 10:33:24 EDT 2010
On 02:13 pm, chris at simplistix.co.uk wrote:
>On 30/09/2010 14:39, Jonathan Lange wrote:
>>On Thu, Sep 30, 2010 at 2:36 PM, Chris Withers<chris at simplistix.co.uk>
>>wrote:
>>...
>>>
>>>Is there any way I can get both errbacks *and* exceptions handled
>>>nicely in
>>>my `loop` call?
>>
>>You know about defer.maybeDeferred, right?
>
>Yep, the problem is with `loop` implemented like so:
>
>def loop():
> d = maybeDeferred(doStuff)
> d.addErrback(partial(log.err,_why='Unhandled scheduled exception'))
Names that begin with an underscore are private. Also, partial is a
pointless complexification here.
def loop():
d = maybeDeferred(doStuff)
d.addErrback(log.err, 'Unhandled scheduled exception')
>...the logging is odd:
>
>2010-09-30 15:07:03,161 ERROR : log (22194|7f41910b26e0):
>Unhandled Error
>Traceback (most recent call last):
> File "test_looping.py", line 47, in <module>
> reactor.run()
> File "/twisted/internet/base.py", line 1166, in run
> self.mainLoop()
> File "/twisted/internet/base.py", line 1175, in mainLoop
> self.runUntilCurrent()
>--- <exception caught here> ---
> File "/twisted/internet/base.py", line 779, in runUntilCurrent
> call.func(*call.args, **call.kw)
> File "test_looping.py", line 30, in __call__
> del self.connector
>exceptions.AttributeError: Break instance has no attribute 'connector'
This is not logged by your code. Do you recognize that?
>
>called 4
>called 5
>/twisted/internet/defer.py:262: DeprecationWarning: Don't pass strings
>(like 'Break!') to failure.Failure (replacing with a DefaultException).
> fail = failure.Failure(fail)
>2010-09-30 15:07:05,167 ERROR : log (22194|7f41910b26e0):
>Unhandled scheduled exception
>Traceback (most recent call last):
>Failure: twisted.python.failure.DefaultException: Break!
This comes from some code not included in the code you posted. It looks
like you're using Failure wrong though. Quoting from above:
Don't pass strings (like 'Break!') to failure.Failure.
>
>So, how come my log.err doesn't get used for the AttributeError on
>connector?
I'm sure it doesn't help for me to simply repeat myself, since if it
didn't make sense the first time probably won't make sense the third or
fourth time. I don't know what else to say though.
log.err is an errback on the Deferred you created in loop.
An errback is called (roughly) when a Deferred fires with a Failure.
Your Deferred *never* fires with a Failure corresponding to that
AttributeError. This is the most important thing. If you don't
understand this, say so and we can talk about it some more. Everything
else is just confusing particulars.
Unfortunately maybeDeferred cannot help here. It solves a slightly
related problem and does nothing about this one. You may well want to
use it, but it's not going to address your `AttributeError` issue in any
way, because of what I said above, and will repeat here for emphasis:
The AttributeError never becomes an error result on any Deferred. It is
caught inside the reactor implementation, logged there by Twisted
itself, and then thrown away forever.
Jean-Paul
More information about the Twisted-Python
mailing list