简体   繁体   English

如何获取 python 中嵌套异常的堆栈跟踪?

[英]How to get the stack trace of a nested exeption in python?

If an exception is raised I'd like to analyse the stack trace in python that tells about where exactly the problem is in the source code file.如果引发异常,我想分析 python 中的堆栈跟踪,它告诉您问题在源代码文件中的确切位置。

Of course for that purpose the module traceback exists.当然,为此目的,存在模块traceback And that works fine for regular exceptions.这适用于常规异常。 But how do you deal with this situation if nested exceptions occur?但是如果发生嵌套异常,你如何处理这种情况呢?

Consider this example:考虑这个例子:

def test():
    try:
        a = 0
        b = 5 / a
    except Exception as ee1:
        assert False

test()

This example prints two exceptions:此示例打印两个异常:

Traceback (most recent call last):
  File "./test4d.py", line 12, in test
    b = 5 / a
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./test4d.py", line 18, in <module>
    test()
  File "./test4d.py", line 14, in test
    assert False
AssertionError

So information about both exceptions is known to the interpreter.因此,解释器知道有关这两种异常的信息。 I therefore like to retrieve these two pieces of information from Python: The stack trace of the assert statement (used as an example here to cause an exception) and the stack trace of the division by zero exception (used as an example here to cause an exception).因此,我想从 Python 中检索这两条信息:assert 语句的堆栈跟踪(此处用作示例导致异常)和除以零异常的堆栈跟踪(此处用作示例导致异常)例外)。 How can I do that?我怎样才能做到这一点?

And the second part of the question: How can I do that in a structured way?问题的第二部分:我怎样才能以结构化的方式做到这一点? The module traceback can be used to get more information about an existing exception.模块traceback可用于获取有关现有异常的更多信息。 But I do not want to print the exception, I want to store it.但我不想打印异常,我想存储它。 Therefore I'd like to get the stack trace as a tuple of instances of some class where each instance represents the data within each stack frame.因此,我想将堆栈跟踪作为一些 class 实例的元组,其中每个实例代表每个堆栈帧中的数据。 How can I do that ?怎么做?

There is a variable named __context__ associated with an exception.有一个名为__context__的变量与异常相关联。 This variable can be used to access nested exceptions.此变量可用于访问嵌套异常。 See this example:看这个例子:

import traceback

def test():
    try:
        a = 0
        b = 5 / a
    except Exception as ee1:
        assert False

try:
    test()
except Exception as ee:
    print(repr(ee))
    stackTraceList = traceback.extract_stack(ee.__traceback__.tb_frame)
    del stackTraceList[0]
    for frame in stackTraceList:
        print("\t", frame)

    if ee.__context__:
        print(repr(ee.__context__))
        stackTraceList = traceback.extract_stack(ee.__context__.__traceback__.tb_frame)
        del stackTraceList[0]
        for frame in stackTraceList:
            print("\t", frame)

This will output the following text:这将 output 以下文本:

AssertionError()
ZeroDivisionError('division by zero',)
     <FrameSummary file ./example.py, line 8 in test>

That indicates that both exceptions can be identified and their stack traces can be iterated through.这表明可以识别这两个异常并且可以迭代它们的堆栈跟踪。

For convenience I implemented a simple helper module to process exceptions and stack traces named jk_exceptionhelper .为方便起见,我实现了一个简单的帮助模块来处理名为jk_exceptionhelper的异常和堆栈跟踪。 You can install this module using pip .您可以使用pip安装此模块。 For details have a look at the GIT repository: https://github.com/jkpubsrc/python-module-jk-exceptionhelper有关详细信息,请查看 GIT 存储库: https://github.com/jkpubsrc/python-module-jk-exceptionhelper

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

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