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

Phil Mayers p.mayers at imperial.ac.uk
Thu Sep 30 07:46:54 MDT 2010


On 30/09/10 14:36, Chris Withers wrote:
>
> Indeed, but, as I keep saying, I need to build a scheduler that's
> resilient to errors in the tasks its running ;-)

Sure.

>
>>> Most prominent is reactor.callLater.
>
> ...which I'm not actually using, it was just a small-as-possible way I
> could simulate the failure mode (rather than the specific failure) I
> need to protect against.

Ah.

> Actually, what appears to work is simply changing `loop` to not be an
> async fuction:
>
> def loop():
>       try:
>           doStuff()
>       except Exception,e:
>           log.err(None,'Unhandled scheduled exception')
>
> looper = task.LoopingCall(loop)
> looper.start(1.0)
> reactor.run()
>
> This appears to solve most of the problems:
> - the schedule now keeps running regardless
> - exceptions in doStuff and below get logged
>
> However, it now has the problem that if doStuff *does* return a deferred
> and it errbacks, the I get the ugly:

Well, you could do this, which is more Twist-y, and Glyph suggested:

def loop():
   d = defer.maybeDeferred(doStuff, *args)
   d.addErrback(log.err)

This will call doStuff, converting return/exception into 
callback/errback, or if the call returns a deferred itself, just return 
that.

FWIW, you say "if doStuff does return a deferred"; I presume you don't 
really have a single call returning both normal and deferred values, and 
it's actually several different function calls to different pieces of work.

> Is there any way I can get both errbacks *and* exceptions handled nicely
> in my `loop` call?

I think you want maybeDeferred, as above.




More information about the Twisted-Python mailing list