Deferred.callback()或Deferred.errback()可以向调用者引发异常吗?

时间:2014-03-11 15:05:35

标签: python twisted twisted.internet

是否存在这样的情况:调用.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中的结果将是来自Exception的{​​{1}}。如果我致电bad_callback(),则d.errback(Exception())中的结果将是d Exception。但是,在任何一种情况下,都不会向调用者提出异常。

现在,我知道调用bad_errback().callback()会引起调用者异常的几个条件,但这些条件是您违反正确使用延迟的条件。

  • 显然,如果您使用不正确数量的参数拨打.errback().callback(),则会引发.errback()

  • 调用已调用的延迟将会引发TypeError

  • 致电AlreadyCalledError会提出.callback(defer.Deferred())

  • 调用AssertionError相当于调用.errback(),如果没有活动异常,则会.errback(failure.Failure())

真的我的问题归结为:我是否能够安全地依赖于调用NoCurrentExceptionError.callback(result)并且结果永远不会引发异常的行为,只要延迟尚未被调用且结果是否正确?

1 个答案:

答案 0 :(得分: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中编程的风险;有几个例外(MemoryErrorKeyboardInterrupt)可能会在没有任何警告的情况下出现。如果您的整个过程没有被烧毁,那么除了您概述的情况外,callbackerrback不会引发异常。