2017年12月16日 星期六

Python: 在自訂的exception handling中加入traceback來取得錯誤的行號

在我們寫python程式的過程中,難免會在測試時看到程式因Exception/Error而中止。
中止的時候,會看到畫面印出在哪一行出錯。例如程式當中有一行:
 
int('abc') 
我們會看到以下的錯誤訊息。錯誤訊息主要分成三個部份,分別用不同的底色來表示(之後依序簡稱訊息1、訊息2、訊息3):
Traceback (most recent call last):
  File "./traceback_test.py", line 7, in <module>
    int('abc')
ValueError: invalid literal for int() with base 10: 'abc'
 如果我們用了try...except如下:
try:
    int('abc')
except Exception as e:
    print(e)  
則會得到以下的結果,只有訊息3,錯誤的行號不見了:
invalid literal for int() with base 10: 'abc'
要如何取得訊息1(以取得發生錯誤的行號)和訊息2,甚至是完全一樣的資訊呢?我們需要使用traceback這個module。以下是一個簡單的範例供參考,如果想要更深入瞭解,可以去找python文件:
#!/usr/bin/python3

import sys, traceback

try:
    int('abc')
except Exception as e:
    ex_type, ex, tb = sys.exc_info() #此行取得ex_type, ex, tb
    #印出訊息1: File "./traceback_test.py", line 7, in <module>\n   int('abc')
    print('----traceback.print_tb(tb)----')
    traceback.print_tb(tb)
    #印出訊息2:ValueError
    print('----print(ex_type.__name__)----')
    print(ex_type.__name__)
    #印出訊息3:invalid literal for int() with base 10: 'abc'
    print('----print(ex)----')
    print(ex)
    #印出完整訊息,含Traceback (most recent call last):
    print('----format_exception(ex_type, ex, tb)----')
    msg_lines = traceback.format_exception(ex_type, ex, tb)
    for l in msg_lines:
        print(l, end='')
    #印出完整訊息,含Traceback (most recent call last):
    print('----traceback.format_exc()----')
    msg_str = traceback.format_exc()
    print(msg_str)

沒有留言:

張貼留言