gpt4 book ai didi

python - @inlineCallbacks 修饰的函数中未处理的异常不会触发 Errback

转载 作者:太空宇宙 更新时间:2023-11-03 16:49:04 27 4
gpt4 key购买 nike

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 捕获:

  1. foo() 被调用并立即返回一个 Deferred。我们向它添加一个 errback,它只打印出它的参数。
  2. 几秒钟后, react 器调用 fail()
  3. fail() 抛出异常。
  4. 异常在生成器产生时被“抛出”到生成器中。 Documentation :

The generator will be sent the result of the Deferred with the 'send' method on generators, or if the result was a failure, 'throw'.

  • 生成器内部不会捕获异常,因此 foo() 的 Deferred 应该调用其 errback:
  • Your inlineCallbacks-enabled generator will return a Deferred object, which ... will fail with a failure object if your generator raises an unhandled exception

  • 在调用 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) try catch 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。

    最佳答案

    您也可以使用 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()

    关于python - @inlineCallbacks 修饰的函数中未处理的异常不会触发 Errback,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36042458/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com