简体   繁体   English

什么是“ <exception caught here> 线在扭曲的回溯是什么意思?

[英]What does “<exception caught here>” line in twisted traceback mean?

For example: 例如:

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

If it is caught there, why it still propagates two frames below? 如果它在那里被捕获,为什么它仍在下面传播两帧? And how to find out from where it was thrown? 以及如何从扔出的地方找出来?

This isn't actually a traceback. 这实际上不是追溯。 This is how a twisted.python.failure.Failure "prints" itself (though to be sure things are ambiguous, the method for doing this is printTraceback ). 这就是twisted.python.failure.Failure本身如何“打印”的方式(尽管要确保事情是模棱两可的,但这样做的方法是printTraceback )。

The reason the line --- <exception caught here> --- is sitting in the middle is that it is dividing information that relates to two different parts of the call stack related to the exception. --- <exception caught here> ---位于中间的原因是,它正在分割与异常相关的调用堆栈的两个不同部分有关的信息。

Above the marker the stack frames are describing what's above the exception handler that decided to create a Failure instance (from the exception and traceback state). 在标记上方,堆栈框架描述了决定创建Failure实例的异常处理程序之上的内容(来自异常和回溯状态)。

For example, consider this simple program: 例如,考虑以下简单程序:

from twisted.python.failure import Failure

def a():
    b()

def b():
    try:
        c()
    except:
        return Failure()

def c():
    1 / 0

f = a()
f.printTraceback()

If you run this then you'll see that above the marker line you get: 如果运行此命令,则会在标记线上方看到以下内容:

File "someprog.py", line 16, in <module>
  f = a()
File "someprog.py", line 5, in a
  return b()

If the call stack is a stack then you can see that these are the two frames that were pushed onto it before the frame that caught the exception and created the Failure . 如果调用堆栈是一个堆栈,则可以看到这是在捕获异常并创建Failure的帧之前被压入其中的两个帧。

And below the marker line you get: 在标记线下方,您将得到:

File "someprog.py", line 9, in b
  c()
File "someprog.py", line 14, in c
  1 / 0

These are the two frames that were on the call stack and got popped off by the exception being raised. 这是调用堆栈上的两个帧,并因引发异常而弹出。

Most often, only the frames below the marker are interesting. 通常,只有标记下方的框架才是有趣的。 The frames above the marker are separated in this format because they're usually deep implementation details of some part of Twisted. 标记上方的框架以这种格式分开,因为它们通常是Twisted某些部分的详细实现细节。 Since Twisted is a cooperative multitasking system, the stack frames in the implementation often don't tell you much that's very useful about the context of the exception (because cooperative multitasking systems in Python can't keep a correspondence between the logical operation being processed and the Python frame objects that are doing the processing). 由于Twisted是协作式多任务处理系统,因此在实现中的堆栈框架通常不会告诉您很多有关异常上下文的信息(因为Python中的协作式多任务处理系统无法保持正在处理的逻辑操作与正在处理的Python框架对象)。

On top of this, understanding your traceback is made more complicated by the fact that the code involved uses inlineCallbacks . 最重要的是,所涉及的代码使用inlineCallbacks使得了解回溯变得更加复杂。 This plays further tricks with the call stack and usually ruins any tracebacks you get out. 这会在调用堆栈中起到进一步的作用,通常会破坏您得到的所有回溯。

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

However, what I notice about this is that it is the attempt to raise an exception into a generator by the implementation of inlineCallbacks that is itself raising another exception. 但是,我注意到的是,通过inlineCallbacks的实现将异常引发到生成器中的尝试本身就是在引发另一个异常。

This TypeError means that self.type is an instance of str . TypeError表示self.typestr的实例。 From this I would guess either that some of the code involved is mis-using Failure or that this application is using Twisted Spread (which mis-uses Failure ). 由此我可能会猜测其中涉及的某些代码滥用了Failure或者此应用程序正在使用Twisted Spread(滥用了Failure )。 The short answer I would prefer to give here is not to combine Twisted Spread and inlineCallbacks : they don't work nicely together. 我想在这里给出的简短答案是不要将Twisted Spread和inlineCallbacks结合inlineCallbacks :它们不能很好地协同工作。

Since I see Zenoss in the paths, I suspect that you did not write most of this code though, so that answer may not be of much help to you... 由于我在路径中看到了Zenoss,因此我怀疑您并未编写大部分代码,因此答案可能对您没有太大帮助...

If you can, and if Twisted Spread is really involved here, you might try upgrading Twisted to see if this problem goes away. 如果可以,并且如果确实涉及Twisted Spread,则可以尝试升级Twisted以查看此问题是否消失。 I think that this is a symptom of http://tm.tl/4520 which was fixed a couple years ago (fix first included in Twisted 11.1.0). 我认为这是几年前已修复的http://tm.tl/4520的症状(该修复程序首次包含在Twisted 11.1.0中)。

If Twisted Spread is not involved then you may need to track down the other code that is mis-using Failure and correct it. 如果不涉及“扭曲传播”,那么您可能需要跟踪其他滥用Failure代码并进行纠正。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM