1

是否存在调用.callback().errback()将向调用者引发异常而不会被延迟捕获的情况?

假设我有以下延迟和回调:

from twisted.internet import defer

def bad_callback(result):
    raise Exception()

def bad_errback(result):
    raise Exception()

d = defer.Deferred()
d.addCallbacks(bad_callback, bad_errback)

如果我打电话d.callback(None),结果d将是Exceptionfrom bad_callback()。如果我跟注d.errback(Exception()),结果d将是Exceptionbad_errback(). 但是,在任何一种情况下,都不会向调用者提出异常。

现在,我确实知道调用.callback().errback()将向调用者引发异常的几种情况,但这些情况是您违反正确使用延迟的情况。

  • 显然,如果您调用.callback().errback()使用不正确数量的参数,它将引发TypeError.

  • 调用已经调用的 deferred 将引发AlreadyCalledError

  • 跟注.callback(defer.Deferred())会引发AssertionError.

  • 调用.errback()等效于调用.errback(failure.Failure())which 将NoCurrentExceptionError在没有活动异常的情况下引发。

真的,我的问题归结为:只要尚未调用 deferred 并且结果正确,我是否可以安全地依赖调用.callback(result)或结果永远不会引发异常的行为?.errback(exception_or_failure)

4

1 回答 1

2

我运行了您的示例,在底部添加了两行:

d.callback(None)
print("OK!")

并得到这个输出:

Unhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
  File "callbacks.py", line 11, in <module>
    d.callback(None)
  File ".../twisted/internet/defer.py", line 368, in callback
    self._startRunCallbacks(result)
  File ".../twisted/internet/defer.py", line 464, in _startRunCallbacks
    self._runCallbacks()
--- <exception caught here> ---
  File ".../twisted/internet/defer.py", line 551, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "callbacks.py", line 4, in bad_callback
    raise Exception()
exceptions.Exception: 
OK!

因此,在这种特定情况下(正如您自己确定的那样),不,不会重新引发异常。

在一般情况下,有几个地方异常会有效地传播出去;如果你有一个MemoryError因为你完全内存不足,那么Deferred实现本身很可能会通过尝试调用函数或其他东西在某处分配一点内存,并且该异常会返回给你。

但这只是在一般情况下使用 Python 编程的风险;有几个例外 ( MemoryError, KeyboardInterrupt) 可能会在没有警告的情况下出现。如果您的整个过程没有烧毁,那么不会,callback并且errback不会引发异常,除非您列出的情况除外。

于 2014-03-11T18:49:53.427 回答