如何从扭曲的inlineCallbacks修饰函数中捕获异常?

时间:2013-12-21 18:35:05

标签: python twisted generator

我开始使用twisted作为我将要使用的lib之一取决于它。在早期的测试中,我很困惑如何捕获像这样的函数抛出的异常:

@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'时不可能。但是从来没有打过我的错误。

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

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

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

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

我错了,或者这只是一个新的对象,空的,简单的,没有连接回调/错误?

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

非常感谢。

[更新]请参阅此gist了解工作示例代码(Python 2.7.6,Twisted 13.2.0)。

1 个答案:

答案 0 :(得分:3)

在重新阅读docs about Twisted Deferred回调和错误后重新编写它。上面代码和链接gist中的问题是回调和errback缺少的参数。如果我用以下代码替换上面写的内容,则异常被捕获并按预期通过errback通知:

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