【发布时间】:2023-12-06 18:15:01
【问题描述】:
from twisted.internet import reactor
from twisted.internet.defer import inlineCallbacks
def fail():
raise Exception()
@inlineCallbacks
def foo():
yield reactor.callLater(5.0, fail)
def dump(*args, **kwargs):
print 'dump', args, kwargs
d = foo()
d.addErrback(dump)
reactor.run()
这里我们有一个虚拟函数foo(),它产生一个将在 5 秒内触发的 Deferred。当它触发时,会抛出一个异常,我希望它会被与我的* Deferred 对象关联的 errback 捕获:
-
foo()被调用并立即返回一个 Deferred。我们向它添加一个 errback,它只是打印出它的参数。 - 几秒钟后,反应器调用
fail()。 -
fail()抛出异常。 - 异常被“抛出”到生成器的产生点。 Documentation:
生成器将通过生成器上的“发送”方法发送延迟的结果,或者如果结果失败,则“抛出”。
- 异常未在生成器内部捕获,因此
foo()的 Deferred 应调用其 errback:
启用 inlineCallbacks 的生成器将返回一个 Deferred 对象,如果您的生成器引发未处理的异常,该对象将失败并返回一个失败对象
- 在调用 errback 时,应调用
dump()。
改为:
Unhandled Error
Traceback (most recent call last):
File "untitled", line 19, in <module>
reactor.run()
File "/Library/Python/2.7/site-packages/twisted/internet/base.py", line 1192, in run
self.mainLoop()
File "/Library/Python/2.7/site-packages/twisted/internet/base.py", line 1201, in mainLoop
self.runUntilCurrent()
--- <exception caught here> ---
File "/Library/Python/2.7/site-packages/twisted/internet/base.py", line 824, in runUntilCurrent
call.func(*call.args, **call.kw)
File "untitled", line 6, in fail
raise Exception()
exceptions.Exception:
为了进一步测试这一点,我尝试 (a) 直接在 foo() 内引发异常,以及 (b) 尝试在 foo() 内捕获 fail() 引发的异常。
(a) 工作正常,我的 errback 被调用。
(b) 不起作用,并导致相同的问题:
@inlineCallbacks
def foo():
try:
yield reactor.callLater(5.0, fail)
except Exception, e:
print e
这是 Twisted 15.1.0 和 Python 2.7.10。
【问题讨论】: