重新提高Pythonexception并保留堆栈跟踪
我试图捕捉一个线程中的exception,并重新在主线程中提出:
import threading import sys class FailingThread(threading.Thread): def run(self): try: raise ValueError('x') except ValueError: self.exc_info = sys.exc_info() failingThread = FailingThread() failingThread.start() failingThread.join() print failingThread.exc_info raise failingThread.exc_info[1]
这基本上工作,并产生以下输出:
(<type 'exceptions.ValueError'>, ValueError('x',), <traceback object at 0x1004cc320>) Traceback (most recent call last): File "test.py", line 16, in <module> raise failingThread.exc_info[1]
但是,例外的来源指向第16行,在那里发生了重新抬头。 原来的exception来自第7行。我如何修改主线程,以便输出结果如下:
Traceback (most recent call last): File "test.py", line 7, in <module>
你需要使用所有三个参数来提高:
raise failingThread.exc_info[0], failingThread.exc_info[1], failingThread.exc_info[2]
将traceback对象作为第三个参数保存在堆栈中。
从help('raise')
:
如果存在第三个对象而不是
None
,则它必须是一个回溯对象(请参阅标准types层次结构 ),并将其replace为当前位置作为发生exception的位置。 如果存在第三个对象而不是回溯对象或None
,则会引发TypeError
exception。raise
的三种expressionforms有助于在except子句中透明地重新引发exception,但如果要重新引发的exception是当前作用域中最近活动的exception,则不应该优先使用expression式进行引发。
在这种情况下,你不能使用noexpression式版本。
这个代码片段在Python 2和3中均可用:
1 try: ----> 2 raise KeyError('Default key error message') 3 except KeyError as e: 4 e.args = ('Custom message when get re-raised',) #The comma is not a typo, it's there to indicate that we're replacing the tuple that e.args pointing to with another tuple that contain the custom message. 5 raise
你可以这样写:
try: raise ValueError('x') except ValueError as ex: self.exc_info = ex
然后从exception中使用堆栈跟踪?