python Python异常传播
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1891572/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python Exception Propagation
提问by So8res
I'm building a tool where as exceptions propagate upwards, new data about the context of the exception gets added to the exception. The issue is, by the time the exception gets to the top level, all of the extra context data is there, but only the very latest stack trace is shown. Is there an easy way to have an exception show the original stack trace in which it was thrown instead of the last stack trace, or should I do something like grab the original stack trace the first time that the exception propagates?
我正在构建一个工具,当异常向上传播时,有关异常上下文的新数据会添加到异常中。问题是,当异常到达顶层时,所有额外的上下文数据都在那里,但只显示最新的堆栈跟踪。有没有一种简单的方法可以让异常显示抛出它的原始堆栈跟踪而不是最后一个堆栈跟踪,或者我应该做一些诸如在异常传播的第一次获取原始堆栈跟踪之类的事情?
For example, the following code:
例如,以下代码:
def a():
return UNBOUND
def b():
try:
a()
except Exception as e:
raise e
b()
yields the following exception:
产生以下异常:
Traceback (most recent call last):
File "test.py", line 8, in <module>
b()
File "test.py", line 7, in b
raise e
NameError: global name 'UNBOUND' is not defined
where, ideally, I'd like to somehow show the user this:
理想情况下,我想以某种方式向用户展示:
Traceback (most recent call last):
File "test.py", line 8, in <module>
File "test.py", line 2, in a
return UNBOUND
NameError: global name 'UNBOUND' is not defined
As that points the user to the line that the error originally occurred on.
因为这会将用户指向最初发生错误的行。
回答by viraptor
Python exceptions are a bit like java, there is a way to cause the exception to be rethrown without truncating the stack.
Python异常有点像java,有一种方法可以在不截断堆栈的情况下重新抛出异常。
Just use raise
without an argument. The result it:
raise
不用参数就直接使用。结果它:
Traceback (most recent call last):
File "./exc.py", line 11, in <module>
b()
File "./exc.py", line 7, in b
a()
File "./exc.py", line 4, in a
return UNBOUND
NameError: global name 'UNBOUND' is not defined
You can modify some things about the e
object, even if you just raise
without that argument - for example:
您可以修改有关e
对象的一些内容,即使您只是raise
没有该参数 - 例如:
e.args = ("hi!",)
raise
will actually change the exception message. You can probably change the other options too this way - without destroying the stack.
实际上会改变异常消息。您也可以通过这种方式更改其他选项 - 而不会破坏堆栈。