[英]What does “<exception caught here>” line in twisted traceback mean?
例如:
Unhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
File "/opt/zenoss/lib/python/twisted/internet/defer.py", line 388, in errback
self._startRunCallbacks(fail)
File "/opt/zenoss/lib/python/twisted/internet/defer.py", line 455, in _startRunCallbacks
self._runCallbacks()
File "/opt/zenoss/lib/python/twisted/internet/defer.py", line 542, in _runCallbacks
current.result = callback(current.result, *args, **kw)
File "/opt/zenoss/lib/python/twisted/internet/defer.py", line 1076, in gotResult
_inlineCallbacks(r, g, deferred)
--- <exception caught here> ---
File "/opt/zenoss/lib/python/twisted/internet/defer.py", line 1018, in _inlineCallbacks
result = result.throwExceptionIntoGenerator(g)
File "/opt/zenoss/lib/python/twisted/python/failure.py", line 352, in throwExceptionIntoGenerator
return g.throw(self.type, self.value, self.tb)
exceptions.TypeError: exceptions must be classes, or instances, not str
如果它在那里被捕获,为什么它仍在下面传播两帧? 以及如何从扔出的地方找出来?
这实际上不是追溯。 这就是twisted.python.failure.Failure
本身如何“打印”的方式(尽管要确保事情是模棱两可的,但这样做的方法是printTraceback
)。
--- <exception caught here> ---
位于中间的原因是,它正在分割与异常相关的调用堆栈的两个不同部分有关的信息。
在标记上方,堆栈框架描述了决定创建Failure
实例的异常处理程序之上的内容(来自异常和回溯状态)。
例如,考虑以下简单程序:
from twisted.python.failure import Failure
def a():
b()
def b():
try:
c()
except:
return Failure()
def c():
1 / 0
f = a()
f.printTraceback()
如果运行此命令,则会在标记线上方看到以下内容:
File "someprog.py", line 16, in <module>
f = a()
File "someprog.py", line 5, in a
return b()
如果调用堆栈是一个堆栈,则可以看到这是在捕获异常并创建Failure
的帧之前被压入其中的两个帧。
在标记线下方,您将得到:
File "someprog.py", line 9, in b
c()
File "someprog.py", line 14, in c
1 / 0
这是调用堆栈上的两个帧,并因引发异常而弹出。
通常,只有标记下方的框架才是有趣的。 标记上方的框架以这种格式分开,因为它们通常是Twisted某些部分的详细实现细节。 由于Twisted是协作式多任务处理系统,因此在实现中的堆栈框架通常不会告诉您很多有关异常上下文的信息(因为Python中的协作式多任务处理系统无法保持正在处理的逻辑操作与正在处理的Python框架对象)。
最重要的是,所涉及的代码使用inlineCallbacks
使得了解回溯变得更加复杂。 这会在调用堆栈中起到进一步的作用,通常会破坏您得到的所有回溯。
File "/opt/zenoss/lib/python/twisted/internet/defer.py", line 1018, in _inlineCallbacks
result = result.throwExceptionIntoGenerator(g)
File "/opt/zenoss/lib/python/twisted/python/failure.py", line 352, in throwExceptionIntoGenerator
return g.throw(self.type, self.value, self.tb)
exceptions.TypeError: exceptions must be classes, or instances, not str
但是,我注意到的是,通过inlineCallbacks
的实现将异常引发到生成器中的尝试本身就是在引发另一个异常。
此TypeError
表示self.type
是str
的实例。 由此我可能会猜测其中涉及的某些代码滥用了Failure
或者此应用程序正在使用Twisted Spread(滥用了Failure
)。 我想在这里给出的简短答案是不要将Twisted Spread和inlineCallbacks
结合inlineCallbacks
:它们不能很好地协同工作。
由于我在路径中看到了Zenoss,因此我怀疑您并未编写大部分代码,因此答案可能对您没有太大帮助...
如果可以,并且如果确实涉及Twisted Spread,则可以尝试升级Twisted以查看此问题是否消失。 我认为这是几年前已修复的http://tm.tl/4520的症状(该修复程序首次包含在Twisted 11.1.0中)。
如果不涉及“扭曲传播”,那么您可能需要跟踪其他滥用Failure
代码并进行纠正。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.