Deferred.callback()或Deferred.errback()会给调用者引发异常吗?



是否存在调用.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的结果将是bad_callback()Exception。如果我调用d.errback(Exception()), d的结果将是从bad_errback()引发的Exception。但是,在这两种情况下,异常都不会被引发给调用者。

现在,我确实知道在一些情况下调用.callback().errback()会给调用者引发异常,但这些情况下你违反了延迟的正确使用。

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

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

  • 调用.callback(defer.Deferred())将引发一个AssertionError

  • 调用.errback()相当于调用.errback(failure.Failure()),如果没有活动异常,将引发NoCurrentExceptionError

真的我的问题归结为:我可以安全地依赖的行为,调用.callback(result).errback(exception_or_failure)的结果永远不会引发异常,只要延迟还没有被调用,结果是正确的?

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

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)可能在没有警告的情况下出现。如果您的整个过程没有被烧毁,那么callbackerrback不会引发异常,除非在您概述的情况下。

相关内容

最新更新