[Twisted-Python] FirstError handling from defer.gatherResults()?

Jean-Paul Calderone exarkun at divmod.com
Wed Nov 5 00:36:24 EST 2008

On Wed, 05 Nov 2008 14:00:56 +1100, Justin Warren <daedalus at eigenmagic.com> wrote:
>On Wed, 2008-11-05 at 02:51 +0100, Terry Jones wrote:
>> Hi Justin
>> >>>>> "Justin" == Justin Warren <daedalus at eigenmagic.com> writes:
>> Justin> If an error occurs, gatherResults() behaves like
>> Justin> DeferredList(fireOnOneErrback=True), but the errback will receive a
>> Justin> FirstError object, not a Failure.
>> Justin> Normally, I'd do something like this in an Errback:
>> Justin> def cb_handle_failure(failure):
>> Justin>   e = failure.trap(MyNonFatalException)
>> Justin> But what is the right way to do this when I receive a FirstError?
>> The FirstError holds the original failure in an attribute called
>> subFailure. So you should be able to do
>>     e = failure.value.subFailure.trap(MyNonFatalException)
>Yes, ok. That's what I thought I should be doing, however trial appears
>to still think that the error I've trapped has occurred, and ERRORs the
>test. Am I not clearing state somewhere? I thought that simply handling
>the failure (and not returning a Failure from the errback) would stop

The Deferred in the list you passed to gatherResults still failed
because gatherResults doesn't pass consumeErrors=True to the DeferredList
it created.  So even though you trapped the failure from the Deferred
gatherResults returned, the original Deferred still has an unhandled
failure and your test gets an error.

To fix this, use DeferredList instead of gatherResults (or your own
version of gatherResults that does pass consumeErrors=True) or add
your own errbacks to all the Deferreds in the list after you've
passed the list to gatherResults.


More information about the Twisted-Python mailing list