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对象相关联的错误捕获:
foo()
并立即返回延迟。我们为它添加一个errback,它只打印出它的参数。fail()
。fail()
抛出异常。生成器将通过发送'发送延迟的结果。关于生成器的方法,或者如果结果是失败的话,抛出'。
foo()
的Deferred应该调用它的errback:你的inlineCallbacks启用的生成器将返回一个Deferred对象,如果你的生成器引发了一个未处理的异常,它将失败并显示失败对象
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)尝试捕获fail()
内foo()
引发的异常。
(a)工作正常,我的错误被召回。
(b)不起作用,导致同样的问题:
@inlineCallbacks
def foo():
try:
yield reactor.callLater(5.0, fail)
except Exception, e:
print e
这是Twisted 15.1.0和Python 2.7.10。
答案 0 :(得分:1)
你也可以使用deferLater
,因为这会像你想要的那样返回Deferred
。
from twisted.internet import task, defer, reactor
def fail(*args):
raise Exception()
def error(*args):
print(args)
def dump(*args, **kwargs):
print('dump', args, kwargs)
@defer.inlineCallbacks
def foo():
d = task.deferLater(reactor, 1.0, fail)
d.addErrback(error)
yield d
D = foo()
D.addCallback(dump)
reactor.run()
答案 1 :(得分:0)
啊,reactor.callLater
没有返回延期。您可以使用
def fail(_):
raise Exception()
@inlineCallbacks
def foo():
d = Deferred()
d.addCallback(fail)
reactor.callLater(1.0, d.callback, None)
yield d