给定文件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__
哪个可行,但是很麻烦,我希望使用一些已经可以解决此问题的标准库模块。
最佳答案
您想使用 format_exception
函数:
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
,则此函数将不打印联合异常,而仅显示最后一个异常。关于python - 使用 'raise from'语法时对链式异常的完整追溯,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56604481/