如何将捕获的异常(其描述和堆栈跟踪)转换为外部使用的str ?
try:
method_that_can_raise_an_exception(params)
except Exception as e:
print(complete_exception_description(e))
如何将捕获的异常(其描述和堆栈跟踪)转换为外部使用的str ?
try:
method_that_can_raise_an_exception(params)
except Exception as e:
print(complete_exception_description(e))
当前回答
如果你的目标是让异常和stacktrace消息看起来与python抛出错误时完全一样,那么以下代码在python 2+3中都适用:
import sys, traceback
def format_stacktrace():
parts = ["Traceback (most recent call last):\n"]
parts.extend(traceback.format_stack(limit=25)[:-2])
parts.extend(traceback.format_exception(*sys.exc_info())[1:])
return "".join(parts)
# EXAMPLE BELOW...
def a():
b()
def b():
c()
def c():
d()
def d():
assert False, "Noooh don't do it."
print("THIS IS THE FORMATTED STRING")
print("============================\n")
try:
a()
except:
stacktrace = format_stacktrace()
print(stacktrace)
print("THIS IS HOW PYTHON DOES IT")
print("==========================\n")
a()
它的工作原理是从堆栈中删除最后一个format_stacktrace()调用,并加入其余的调用。当运行时,上面的示例给出以下输出:
THIS IS THE FORMATTED STRING
============================
Traceback (most recent call last):
File "test.py", line 31, in <module>
a()
File "test.py", line 12, in a
b()
File "test.py", line 16, in b
c()
File "test.py", line 20, in c
d()
File "test.py", line 24, in d
assert False, "Noooh don't do it."
AssertionError: Noooh don't do it.
THIS IS HOW PYTHON DOES IT
==========================
Traceback (most recent call last):
File "test.py", line 38, in <module>
a()
File "test.py", line 12, in a
b()
File "test.py", line 16, in b
c()
File "test.py", line 20, in c
d()
File "test.py", line 24, in d
assert False, "Noooh don't do it."
AssertionError: Noooh don't do it.
其他回答
对于Python 3.5+ 使用回溯。TracebackException,它可以处理在任何地方捕获的异常。
def print_trace(ex: BaseException):
print(''.join(traceback.TracebackException.from_exception(ex).format()))
例子
import traceback
try:
1/0
except Exception as ex:
print(''.join(traceback.TracebackException.from_exception(ex).format()))
> >输出
Traceback (most recent call last):
File "your_file_name_here.py", line 29, in <module>
1/0
ZeroDivisionError: division by zero
它与from_exec()和format_exception()相同:
a = ''.join(traceback.TracebackException.from_exception(ex).format())
b = traceback.format_exc()
c = ''.join(traceback.format_exception(type(ex), ex, ex.__traceback__))
print(a == b == c) # This is True !!
>>> import sys
>>> import traceback
>>> try:
... 5 / 0
... except ZeroDivisionError as e:
... type_, value_, traceback_ = sys.exc_info()
>>> traceback.format_tb(traceback_)
[' File "<stdin>", line 2, in <module>\n']
>>> value_
ZeroDivisionError('integer division or modulo by zero',)
>>> type_
<type 'exceptions.ZeroDivisionError'>
>>>
>>> 5 / 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
您可以使用sys.exc_info()收集信息,并使用traceback模块中的函数对其进行格式化。 下面是一些格式化的例子。
整个异常字符串位于:
>>> ex = traceback.format_exception(type_, value_, traceback_)
>>> ex
['Traceback (most recent call last):\n', ' File "<stdin>", line 2, in <module>\n', 'ZeroDivisionError: integer division or modulo by zero\n']
我定义了以下helper类:
import traceback
class TracedExeptions(object):
def __init__(self):
pass
def __enter__(self):
pass
def __exit__(self, etype, value, tb):
if value :
if not hasattr(value, 'traceString'):
value.traceString = "\n".join(traceback.format_exception(etype, value, tb))
return False
return True
我以后可以这样使用:
with TracedExeptions():
#some-code-which-might-throw-any-exception
之后可以像这样消耗它:
def log_err(ex):
if hasattr(ex, 'traceString'):
print("ERROR:{}".format(ex.traceString));
else:
print("ERROR:{}".format(ex));
(背景:我很沮丧,因为使用承诺和异常一起,不幸的是将异常在一个地方引发到另一个地方的on_rejected处理程序,因此很难从原始位置获得回溯)
在Python 3中,以下代码将格式化Exception对象,与使用traceback.format_exc()获得的结果完全相同:
import traceback
try:
method_that_can_raise_an_exception(params)
except Exception as ex:
print(''.join(traceback.format_exception(etype=type(ex), value=ex, tb=ex.__traceback__)))
这样做的好处是只需要Exception对象(多亏了记录的__traceback__属性),因此可以更容易地将其作为参数传递给另一个函数进行进一步处理。
请参阅traceback模块,特别是format_exc()函数。在这里。
import traceback
try:
raise ValueError
except ValueError:
tb = traceback.format_exc()
else:
tb = "No error"
finally:
print tb