2009-12-11 180 views
8

我正在構建一個工具,在異常向上傳播時,有關異常上下文的新數據將被添加到異常中。問題是,在異常到達頂層時,所有額外的上下文數據都在那裏,但只顯示最新的堆棧跟蹤。是否有一種簡單的方法可以讓異常顯示原始堆棧跟蹤而不是最後一個堆棧跟蹤,或者我應該像第一次抓取原始堆棧跟蹤那樣異常傳播?Python異常傳播

例如,下面的代碼:

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 

因爲這將用戶指向最初發生錯誤的行。

回答

26

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 

將真正改變異常消息。您也可以通過這種方式更改其他選項 - 而不會破壞堆棧。