[英]Re-raise Python exception and preserve stack trace
我试图在一个线程中捕获异常并在主线程中重新引发它:
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行,其中发生了重新加注。 原始异常来自第7行。如何修改主线程以使输出显示:
Traceback (most recent call last):
File "test.py", line 7, in <module>
在Python 2中,您需要使用所有三个参数来引发:
raise failingThread.exc_info[0], failingThread.exc_info[1], failingThread.exc_info[2]
传递traceback对象作为第三个参数保留堆栈。
来自help('raise')
:
如果存在第三个对象而不是
None
,则它必须是一个回溯对象(请参阅标准类型层次结构一节),并将其替换为当前位置作为发生异常的位置。 如果存在第三个对象而不是回溯对象或None
,则引发TypeError
异常。raise
的三表达式形式对于在except子句中透明地重新引发异常很有用,但如果要重新引发的异常是当前作用域中最近活动的异常,则应该首选raise
而不使用表达式。
在这种特殊情况下,您不能使用no表达式版本。
对于Python 3(根据评论):
raise failingThread.exc_info[1].with_traceback(failingThread.exc_info[2])
或者您可以使用raise ... from ...
简单地链接异常,但是会在原因属性中附加原始上下文引发链接异常,这可能是也可能不是您想要的。
这段代码在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
然后使用异常中的stacktrace?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.