Python异常传播

时间:2009-12-11 23:37:42

标签: python exception

我正在构建一个工具,当异常向上传播时,有关异常上下文的新数据会被添加到异常中。问题是,当异常到达顶级时,所有额外的上下文数据都存在,但只显示最新的堆栈跟踪。是否有一种简单的方法可以让异常显示抛出它的原始堆栈跟踪而不是最后一个堆栈跟踪,或者我应该在第一次异常传播时执行类似抓取原始堆栈跟踪的操作?

例如,以下代码:

def a():
    return UNBOUND
def b():
    try:
        a()
    except Exception as e:
        raise e
b()

产生以下异常:

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

理想情况下,我想以某种方式向用户显示:

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

因为这会将用户指向最初发生错误的行。

1 个答案:

答案 0 :(得分:29)

Python异常有点像java,有一种方法可以在不截断堆栈的情况下重新抛出异常。

只需使用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

您可以修改有关e对象的一些内容,即使您只是raise没有该参数 - 例如:

e.args = ("hi!",)
raise 

实际上会更改异常消息。您可以通过这种方式更改其他选项 - 不会破坏堆栈。