使用“raise from”语法时对链接异常的完全回溯

2024-09-28 01:33:06 发布

您现在位置:Python中文网/ 问答频道 /正文

给定文件errors.py

from traceback import format_tb, extract_tb

class MyError(Exception):
    def __init__(self, message):
        self.message = message

class MySecondError(Exception):
    def __init__(self, message):
        self.message = message

try:
    try:
        raise MyError("Something specific has happened")
    except Exception as error:
        raise MySecondError("Something general has happened") from error
except Exception as error:
    print("".join(format_tb(error.__traceback__)))

运行python errors.py时,输出为:

  File "errors.py", line 15, in <module>
    raise MySecondError("Something general has happened") from error

这方面的主要问题是,只有“链”中的“最高”错误的回溯(MySecondError),没有关于包装错误的信息(MyError

如果我删除最后的try/except包装器以便不捕获链式错误,我会得到更好的输出:

Traceback (most recent call last):
  File "exceptions.py", line 14, in <module>
    raise MyError("Something specific has happened")
__main__.MyError: Something specific has happened

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "exceptions.py", line 16, in <module>
    raise MySecondError("Something general has happened") from error
__main__.MySecondError: Something general has happened

它具有完整错误链和连接行(Traceback (most recent call last):The above exception was the direct cause of the following exception:)的回溯和每个错误的字符串表示

理想情况下,我希望捕获这些输出行以将它们定向到其他位置(例如记录器)

我的一个解决方案是迭代error.__context__并手动添加连词:

except Exception as error:
    inner_error = error

    while inner_error:
        if inner_error is not error:
            print("\nThe above exception was the direct cause of the following exception:\n")

        print("Traceback (most recent call last):")
        print("".join(format_tb(inner_error.__traceback__) + [ str(error) ])) 
        inner_error = inner_error.__context__

这是可行的,但它是黑客的,我更愿意使用一些标准的库模块,它已经处理了这个问题


Tags: thefrompymessage错误exceptionerrorsomething
1条回答
网友
1楼 · 发布于 2024-09-28 01:33:06

您想使用^{}函数:

from traceback import format_tb, format_exception

class MyError(Exception):
    def __init__(self, message):
        self.message = message

class MySecondError(Exception):
    def __init__(self, message):
        self.message = message

try:
    try:
        raise MyError("Something specific has happened")
    except Exception as error:
        raise MySecondError("Something general has happened") from error
except Exception as error:
    print("".join(format_exception(error.__class__, error, error.__traceback__)))

给出:

$ python3 /tmp/a.py 
Traceback (most recent call last):
  File "/tmp/a.py", line 13, in <module>
    raise MyError("Something specific has happened")
MyError: Something specific has happened

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/tmp/a.py", line 15, in <module>
    raise MySecondError("Something general has happened") from error
MySecondError: Something general has happened

如果指定chain=False,此函数将不打印连接异常,而只打印最后一个异常

相关问题 更多 >

    热门问题