获取异常描述和堆栈跟踪,全部作为字符串

627 投票
12 回答
418179 浏览
提问于 2025-04-16 09:13

如何将捕获到的 Exception(它的描述和堆栈跟踪信息)转换成 str 以便外部使用?

try:
    method_that_can_raise_an_exception(params)
except Exception as e:
    print(complete_exception_description(e))

12 个回答

91

在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__属性),所以可以更方便地把它作为参数传递给其他函数进行进一步处理。

125

让我们创建一个相对复杂的错误追踪信息,以展示我们可以获取完整的错误追踪。

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!

仅获取字符串

如果你真的只想要字符串,可以使用 traceback.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!
883

可以看看 traceback 这个模块,特别是里面的 format_exc() 函数。点击这里了解更多。

import traceback

try:
    raise ValueError
except ValueError:
    tb = traceback.format_exc()
else:
    tb = "No error"
finally:
    print tb

撰写回答