[Twisted-Python] Unhandled error in Deferred with twisted-8.2.0, but not with twisted-2.1.0

glyph at divmod.com glyph at divmod.com
Fri Jun 26 11:48:47 MDT 2009


On 04:33 pm, benjamin.rutt at gs.com wrote:
>Am currently trying to upgrade to twisted-8.2.0.  For some reason,
>twisted-8.2.0 thinks my deferred below was gc'd with an unhandled 
>error,
>and tells me about it upon reactor exit.  With
>python-2.4.2/twisted-2.1.0, no issues.  With 
>python-2.6.1/twisted-8.2.0,
>I see these issues.  Any ideas why?  Thanks.

A second Deferred is created during getProcessOutput to track the ending 
of the process as distinct from the end of its output.  You have to 
catch that exception as well if you don't want any exceptions logged.

Arguably, this is a bug, since it changes the behavior and complicates 
error handling; if you think so, feel free to file a ticket on the 
tracker.  I just learned about this behavior myself, in the process of 
tracking down your question :).

This behavior was changed in:

    http://twistedmatrix.com/trac/changeset/24810

as part of a fix for:

    http://twistedmatrix.com/trac/ticket/3239

and that took place after 8.1 but before 8.2.  In the meanwhile, you 
could upgrade to 8.2 before going to 8.2 to avoid this issue; going from 
8.1 to 8.2 should be significantly easier than going from 2.1 to 8.1 ;).

If you'd still like to upgrade all the way, here's a "correct" version 
of your program (with spurious imports removed), according to the 
behavior in 8.2.0:

#!/usr/bin/env python
from twisted.internet import reactor
from twisted.internet.utils import getProcessOutput

def foo():
    d = getProcessOutput('/some/non/existent/program')
    def cb(result):
        print 'cb: %s' % (result)
    def eb(failure):
        failure.trap(IOError)
        def endedException(ended):
            print 'really, caught it!'
        failure.value.processEnded.addErrback(endedException)
        print 'eb caught the failure!'
    d.addCallback(cb)
    d.addErrback(eb)

def stopit():
    print 'Stopping reactor.'
    reactor.stop()
    print 'Stopped.'

reactor.callWhenRunning(foo)
reactor.callLater(1.0, stopit)
reactor.run()




More information about the Twisted-Python mailing list