如何将捕获的异常(其描述和堆栈跟踪)转换为外部使用的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,以演示我们得到完整的stacktrace:
def raise_error():
raise RuntimeError('something bad happened!')
def do_something_that_might_error():
raise_error()
记录完整的堆栈跟踪
最佳实践是为您的模块设置一个记录器。它将知道模块的名称,并且能够更改级别(在其他属性中,例如处理程序)
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
我们可以使用这个日志来获取错误:
try:
do_something_that_might_error()
except Exception as error:
logger.exception(error)
日志:
ERROR:__main__:something bad happened!
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<stdin>", line 2, in do_something_that_might_error
File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!
所以我们得到的输出和我们有错误时是一样的:
>>> do_something_that_might_error()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in do_something_that_might_error
File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!
只获取字符串
如果你真的只想要字符串,使用回溯。取而代之的是Format_exc函数,在这里演示了记录字符串:
import traceback
try:
do_something_that_might_error()
except Exception as error:
just_the_string = traceback.format_exc()
logger.debug(just_the_string)
日志:
DEBUG:__main__:Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<stdin>", line 2, in do_something_that_might_error
File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!
其他回答
让我们创建一个相当复杂的stacktrace,以演示我们得到完整的stacktrace:
def raise_error():
raise RuntimeError('something bad happened!')
def do_something_that_might_error():
raise_error()
记录完整的堆栈跟踪
最佳实践是为您的模块设置一个记录器。它将知道模块的名称,并且能够更改级别(在其他属性中,例如处理程序)
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
我们可以使用这个日志来获取错误:
try:
do_something_that_might_error()
except Exception as error:
logger.exception(error)
日志:
ERROR:__main__:something bad happened!
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<stdin>", line 2, in do_something_that_might_error
File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!
所以我们得到的输出和我们有错误时是一样的:
>>> do_something_that_might_error()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in do_something_that_might_error
File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!
只获取字符串
如果你真的只想要字符串,使用回溯。取而代之的是Format_exc函数,在这里演示了记录字符串:
import traceback
try:
do_something_that_might_error()
except Exception as error:
just_the_string = traceback.format_exc()
logger.debug(just_the_string)
日志:
DEBUG:__main__:Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<stdin>", line 2, in do_something_that_might_error
File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!
我的2美分。
import sys, traceback
try:
...
except Exception, e:
T, V, TB = sys.exc_info()
print ''.join(traceback.format_exception(T,V,TB))
如果你想将你的回溯转换为dict的列表(适用于python > 3.5):
from traceback import TracebackException
def list_traceback(exc_value: BaseException):
result = list()
# get previous fails, so errors are appended by order of execution
if exc_value.__context__:
result += list_traceback(exc_value.__context__)
# convert Exception into TracebackException
tbe = TracebackException.from_exception(exc_value)
# get stacktrace (cascade methods calls)
error_lines = list()
for frame_summary in tbe.stack:
summary_details = {
'filename': frame_summary.filename,
'method' : frame_summary.name,
'lineno' : frame_summary.lineno,
'code' : frame_summary.line
}
error_lines.append(summary_details)
# append error, by order of execution
result.append({"error_lines": error_lines,
"type" : tbe.exc_type.__name__,
"message" : str(tbe)})
return result
这将是结果(一个例子):
[
{
"error_lines": [
{
"filename": "/home/demo/file2.py",
"method": "do_error_2",
"lineno": 18,
"code": "a=1/0"
}
],
"type": "ZeroDivisionError",
"message": "division by zero"
},
{
"error_lines": [
{
"filename": "/home/demo/file_main.py",
"method": "demo2",
"lineno": 50,
"code": "file2.DEMO().do_error_2()"
},
{
"filename": "/home/demo/file2.py",
"method": "do_error_2",
"lineno": 20,
"code": "raise AssertionError(\"Raised inside the except, after division by zero\")"
}
],
"type": "AssertionError",
"message": "Raised inside the except, after division by zero"
}
]
在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__属性),因此可以更容易地将其作为参数传递给另一个函数进行进一步处理。
对于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 !!