【问题标题】:How to catch exceptions from a twisted inlineCallbacks decorated function?如何从扭曲的 inlineCallbacks 装饰函数中捕获异常?
【发布时间】:2013-12-21 18:35:05
【问题描述】:

我开始使用 twisted,因为我将使用的库之一取决于它。在早期的测试中,我对如何捕获这样的函数中抛出的异常感到困惑:

@defer.inlineCallbacks
def read_input_status(self, address, length, callback):
    assert callback
    # ...

如果callbackNone一个AssertionError被抛出,所以我试着看一下......函数调用是这样的:

def cb():
    pass
def eb():
    pass

d = task.deferLater(reactor, 1, client.read_input_status, 0x0000, 8, None)
d.addCallback(cb)
d.addErrback(eb)

我在这里调用deferLater 是为了能够处理错误,因为我知道在使用“callLater”时这是不可能的。但是我的 errback 永远不会被调用。

奇怪的是,当我尝试调试并查看扭曲的库的代码时,我想我已经看到了一个原因,为什么我的 errback 没有效果。我装饰的生成器函数(下面的参数g)由twisted 的defer._inlineCallbacks 实现调用,如下所示(略):

def _inlineCallbacks(result, g, deferred):
    # ...
    while 1:
        try:
            # ...
            result = g.send(result)
        except:
            deferred.errback()
            return deferred

我确实在最后一部分看到我的异常弹出,然后调用了延迟的 errback。但是:那不是我的延迟...如果我在调试器的调用层次结构中进行一次调用,我会看到哪个延迟对象实际上传递给_inlineCallbacks

def unwindGenerator(*args, **kwargs):
    # ...
    return _inlineCallbacks(None, gen, Deferred())

我弄错了还是这只是一个新对象,空的,普通的,没有附加回调/错误返回?

抱歉,冗长的阐述。找不到任何直接相关的内容,除了 this SO post 我无法直接看到它如何解决我的问题。

非常感谢。

[更新] 请参阅此gist 以获取工作示例代码(Python 2.7.6、Twisted 13.2.0)。

【问题讨论】:

  • sscce.org 会很好。您的代码不完整,因此无法运行,因此不容易调试。该错误可能存在于您尚未共享的代码的某些部分中,在这种情况下,任何人都可以帮助您的唯一方法是做出令人难以置信的幸运猜测。
  • 添加了示例的要点,让您进入我所指的堆栈跟踪:gist.github.com/anonymous/8080166

标签: python twisted generator


【解决方案1】:

在重读 docs about Twisted Deferred 回调和 errbacks 后想通了。上面代码和链接要点中的问题是缺少回调和 errback 的参数。如果我用以下代码替换上面写的内容,异常会被很好地捕获并按预期通过 errback 通知:

def cb(result):
    pass
def eb(failure):
    pass

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2013-08-22
    • 2019-10-05
    • 2019-06-23
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    相关资源
    最近更新 更多