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