Opened 16 years ago

Closed 16 years ago

#1880 enhancement closed worksforme (worksforme)

deferreds should let you override the "Unhandled error in Deferred" behaviour

Reported by: ghazel Owned by:
Priority: lowest Milestone:
Component: core Keywords:
Cc: Branch:
Author:

Description

Here's a use case:

def do_qux_thing(qux):
  df = make_qux_call(qux)
  def qux_error_counter(failure):
    qux_failures.append(stringify(failure))
    return failure
  df.addErrback(qux_error_counter)
  return df

df = do_qux_thing(qux)
df.addCallback(yay)
# the err is handled in that it is added to the list, so I don't want to see an "Unhandled error in Deferred" message

df2 = do_qux_thing(qux)
df2.addCallback(yay)
# here I wish to explicitly take an action on failure
df2.addErrback(retry)

Basically, I'd like errbacks to chain the same way callbacks do. Perhaps something like:

df.error_handled(failure)

to silence the message.

Change History (4)

comment:1 Changed 16 years ago by ghazel

except you'd probably call it:

df.errorHandled(failure)

comment:2 Changed 16 years ago by Glyph

Priority: normallowest

(A minor nit before we get started: please use the Twisted coding convention when posting bugs in this tracker. You might not like camel case or 80-line-limits but it is how we do things around here.)

I'm not going to close this as invalid immediately so we can have a discussion about it on this ticket. However, I can't imagine that this functionality is actually useful. The error is unhandled, and you're not detecting a particular type of error in your handler. What you're talking about is an alternative logging mechanism (which may be to ignore the failure) and there's already a separate channel for doing that.

If you really want to do things the way you suggest, here's how you implement it -- untested, but I think it gets the idea across:

def doQuxThing(qux):
  df = makeQuxCall(qux)
  def quxErrorCounter(failure):
    quxFailures.append(stringify(failure))
    def finalErrorHandler(finalFailure):
        if finalFailure is failure:
            # the error hasn't changed, which means 'retry' didn't raise a new
            # kind of exception: let's clear out the Deferred so it doesn't log
            # the unhandled error when it GCs
            return None
        return finalFailure
    # Pop the stack, give all the other errbacks and callbacks a chance to run.
    # Adding a callback in here would lead to some misleading results.  (Maybe
    # *this* is the real bug: addErrback should be reentrant.)
    reactor.callLater(0, d.addErrback, finalErrorHandler)
    return failure
  df.addErrback(quxErrorCounter)
  return df

df = doQuxThing(qux)
df.addCallback(yay)

# the err is handled in that it is added to the list, so I don't want to see an
# "Unhandled error in Deferred" message
df2 = doQuxThing(qux)
df2.addCallback(yay)

# here I wish to explicitly take an action on failure
df2.addErrback(retry)

comment:3 Changed 16 years ago by ghazel

Resolution: worksforme
Status: newclosed

Yeah, that works for me.

comment:4 Changed 11 years ago by <automation>

Owner: Glyph deleted
Note: See TracTickets for help on using tickets.