使用Python Twisted时,没有看到"延迟中未处理的错误"的堆栈跟踪

Akh*_*khi 5 python twisted

通过http://krondo.com/an-introduction-to-asynchronous-programming-and-twisted/阅读,我对Twisted有了基本的了解.我已经建立了一些其他人也使用的测试基础设施.如果代码中存在错误或拼写错误,我们会不时地遇到"延迟中未处理的错误"类型错误.问题是并不总是伴随着这些错误的堆栈跟踪,这使得人们很难调试.

我用以下简单代码重现了这个问题:

from twisted.internet import defer, reactor
from twisted.internet.task import deferLater


def sleep(delay):
    """Twisted safe sleep.

    When using Twisted, it is not safe to call time.sleep().  So
    we have this function to emulate the behavior.

    """
    return deferLater(reactor, delay, lambda: None)


@defer.inlineCallbacks
def run_test():
    print 'run_test: start'
    bug()
    yield sleep(1)
    print 'run_test: stop'


@defer.inlineCallbacks
def run_tests():

    def err(arg):
        print 'err', arg
        return arg

    def success(arg):
        print 'success', arg
        return arg

    d = run_test()
    #d.addCallbacks(success, err)

    try:
        yield d
    finally:
        reactor.stop()


reactor.callWhenRunning(run_tests)
reactor.run()
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时,我看到以下输出:

run_test: start
Unhandled error in Deferred:
Run Code Online (Sandbox Code Playgroud)

如果我取消注释上面的addCallbacks()行,那么我得到一些堆栈跟踪信息:

run_test: start
err [Failure instance: Traceback: <type 'exceptions.NameError'>: global name 'bug' is not defined
/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py:1406:unwindGenerator
/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py:1260:_inlineCallbacks
tmp.py:34:run_tests
/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py:1406:unwindGenerator
--- <exception caught here> ---
/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py:1260:_inlineCallbacks
tmp.py:18:run_test
]
Unhandled error in Deferred:
Run Code Online (Sandbox Code Playgroud)

我的问题是,是否有一些方法可以获得堆栈跟踪而无需在所有延迟站点添加回调?

not*_*.no 6

Deferred课程有大量的尝试/除了魔法,以至于错误很好地从最终用户中抽象出来,并且只能轻松获得addErrback.如果发生错误,则表示您已经破坏了功能.在同步应用程序中,您可以将"问题部分"封装在try/except块中.在这种情况下inlineCallbacks,可以使用相同的技术:

try:
    run_test()
except Exception as err:
    # handle error here
finally:
    reactor.stop()
Run Code Online (Sandbox Code Playgroud)

由于错误发生在run_test()函数中,因此在运行该函数时捕获异常,然后根据您的要求处理错误.

但是,如果您不打算"处理"错误,而是希望记录发生错误,那么您应该考虑使用Twisted logger功能.这将捕获您未处理的回溯并将其记录到某处.