使用 Python Twisted 时没有看到 'Unhandled error in Deferred' 的堆栈跟踪
No stack trace seen with 'Unhandled error in Deferred' when using Python Twisted
通读http://krondo.com/an-introduction-to-asynchronous-programming-and-twisted/,对Twisted有了基本的了解。我建立了一个测试基础设施,其他一些人也在使用。如果代码中存在错误或拼写错误,我们有时会遇到 'Unhandled error in Deferred' 类型错误。问题是这些错误并不总是伴随堆栈跟踪,这使得人们很难调试。
我用下面的简单代码重现了这个问题:
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_test: start
Unhandled error in Deferred:
如果我取消注释上面的 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:
我的问题是,是否有某种方法可以获取堆栈跟踪而无需在所有延迟站点添加回调?
Deferred
class 有大量的 try/except 魔力,以至于错误可以很好地从最终用户那里抽象出来,并且只能通过 addErrback
轻松实现.如果出现错误,则表明您的功能已损坏。在同步应用程序中,您可以将 "problem section" 封装在 try/except 块中。在 inlineCallbacks
的情况下,可以使用相同的技术:
try:
run_test()
except Exception as err:
# handle error here
finally:
reactor.stop()
由于bug出现在run_test()
函数中,所以在运行那个函数中捕获异常,然后根据您的要求处理错误。
但是,如果您不打算 "handle" 错误,而是想要记录错误发生,那么您应该考虑使用 Twisted logger
功能。这将捕获您未处理的回溯并将它们记录在某处。
通读http://krondo.com/an-introduction-to-asynchronous-programming-and-twisted/,对Twisted有了基本的了解。我建立了一个测试基础设施,其他一些人也在使用。如果代码中存在错误或拼写错误,我们有时会遇到 'Unhandled error in Deferred' 类型错误。问题是这些错误并不总是伴随堆栈跟踪,这使得人们很难调试。
我用下面的简单代码重现了这个问题:
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_test: start
Unhandled error in Deferred:
如果我取消注释上面的 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:
我的问题是,是否有某种方法可以获取堆栈跟踪而无需在所有延迟站点添加回调?
Deferred
class 有大量的 try/except 魔力,以至于错误可以很好地从最终用户那里抽象出来,并且只能通过 addErrback
轻松实现.如果出现错误,则表明您的功能已损坏。在同步应用程序中,您可以将 "problem section" 封装在 try/except 块中。在 inlineCallbacks
的情况下,可以使用相同的技术:
try:
run_test()
except Exception as err:
# handle error here
finally:
reactor.stop()
由于bug出现在run_test()
函数中,所以在运行那个函数中捕获异常,然后根据您的要求处理错误。
但是,如果您不打算 "handle" 错误,而是想要记录错误发生,那么您应该考虑使用 Twisted logger
功能。这将捕获您未处理的回溯并将它们记录在某处。