在不停止程序的情况下捕获并打印完整的Python异常回溯信息

在不停止程序的情况下捕获并打印完整的Python异常回溯信息

技术背景

在Python开发过程中,当程序出现异常时,我们通常希望在不停止程序的情况下获取完整的异常回溯信息,以便进行调试和问题排查。Python 标准库中的 traceback 模块提供了强大的功能来实现这一需求。

实现步骤

基本用法

要捕获并打印异常回溯信息,首先需要使用 try/except 语句来捕获异常,然后使用 traceback 模块中的相关函数进行处理。

打印回溯信息

以下是一个简单的示例,展示了如何使用 traceback.format_exc() 来捕获并打印完整的回溯信息:

1
2
3
4
5
6
7
8
9
10
11
12
import traceback

def raise_error():
raise RuntimeError('something bad happened!')

def do_something_that_might_error():
raise_error()

try:
do_something_that_might_error()
except Exception as error:
print(traceback.format_exc())

使用日志记录

更好的做法是使用日志记录,通过 logging 模块的 logger.exception() 函数:

1
2
3
4
5
6
7
8
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

try:
do_something_that_might_error()
except Exception as error:
logger.exception(error)

核心代码

获取异常回溯字符串

1
2
3
4
5
6
7
8
9
10
11
12
import traceback

def get_traceback(e):
lines = traceback.format_exception(type(e), e, e.__traceback__)
return ''.join(lines)

try:
1 / 0
except Exception as e:
print('------Start--------')
print(get_traceback(e))
print('------End--------')

直接打印异常回溯信息

1
2
3
4
5
6
import traceback

try:
object.bad_attr
except Exception as exc:
traceback.print_exception(exc)

最佳实践

  • 使用日志记录:避免直接使用 print 语句,使用 logging 模块可以更好地管理日志级别和输出。
  • 捕获特定异常:尽量捕获特定的异常类型,而不是使用通用的 Exception 来避免隐藏其他潜在问题。
  • 及时清理引用:如果使用 sys.exc_info() 获取异常信息,使用完后及时删除引用,避免循环引用。

常见问题

traceback.print_exc()print(traceback.format_exc()) 的区别

traceback.print_exc() 直接打印回溯信息到标准输出,而 print(traceback.format_exc()) 先将回溯信息格式化为字符串,再进行打印。有时候前者可能会与其他输出混合,使用后者可以避免这种问题。

在嵌套异常处理中获取原始异常回溯

在 Python 2.x 中,使用 sys.exc_info() 缓存异常信息,然后在需要的时候使用 traceback.print_exception() 来显示原始异常回溯。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import traceback
import sys

try:
raise TypeError("Oups!")
except Exception, err:
try:
exc_info = sys.exc_info()

try:
raise TypeError("Again !?!")
except:
pass

finally:
traceback.print_exception(*exc_info)
del exc_info

多种打印回溯信息的方式对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import traceback

# 方式一:直接打印格式化后的回溯信息
try:
1 / 0
except Exception:
print(traceback.format_exc())

# 方式二:使用 logger 记录异常和回溯信息
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
try:
1 / 0
except Exception as error:
logger.exception(error)

# 方式三:获取字符串形式的回溯信息
try:
1 / 0
except Exception as e:
tb_str = ''.join(traceback.format_exception(type(e), e, e.__traceback__))
print(tb_str)

在不停止程序的情况下捕获并打印完整的Python异常回溯信息
https://119291.xyz/posts/catch-and-print-full-python-exception-traceback-without-halting-program/
作者
ww
发布于
2025年5月30日
许可协议