本文目录导读:

- 使用
sys.excepthook钩子函数 - 使用
threading.excepthook(线程异常处理) - 装饰器方式捕获函数异常
- 使用
atexit模块处理程序退出时的异常 - 上下文管理器方式
- Web框架中的全局异常处理(以Flask为例)
- 综合实践:生产环境推荐的方案
- 注意事项
在Python中捕获全局异常报错有多种方法,以下是几种常用的实现方式:
使用 sys.excepthook 钩子函数
import sys
import traceback
def global_exception_handler(exc_type, exc_value, exc_traceback):
"""全局异常处理函数"""
# 记录异常信息到文件
with open('error.log', 'a', encoding='utf-8') as f:
f.write(f"异常类型: {exc_type.__name__}\n")
f.write(f"异常值: {exc_value}\n")
f.write("追踪信息:\n")
traceback.print_tb(exc_traceback, file=f)
f.write("-" * 50 + "\n")
# 打印到控制台
print(f"发生未捕获异常: {exc_value}")
# 阻止默认处理(可选)
# sys.exit(1)
# 设置全局异常处理器
sys.excepthook = global_exception_handler
# 测试代码
def test_function():
raise ValueError("测试异常")
test_function()
使用 threading.excepthook(线程异常处理)
import threading
import sys
def thread_exception_handler(args):
"""线程异常处理函数"""
print(f"线程 {args.thread.name} 发生异常:")
print(f"类型: {args.exc_type}")
print(f"值: {args.exc_value}")
# 记录日志
with open('thread_errors.log', 'a') as f:
f.write(f"Thread: {args.thread.name}, Error: {args.exc_value}\n")
# 设置线程异常处理器
threading.excepthook = thread_exception_handler
def worker():
raise RuntimeError("线程中的异常")
# 测试
t = threading.Thread(target=worker)
t.start()
t.join()
装饰器方式捕获函数异常
import functools
import traceback
def catch_exceptions(func):
"""装饰器:捕获函数中的所有异常"""
@functools.wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
print(f"函数 {func.__name__} 发生异常:")
print(f"错误信息: {e}")
traceback.print_exc()
# 记录到文件
with open('function_errors.log', 'a') as f:
f.write(f"Function: {func.__name__}\n")
traceback.print_exc(file=f)
f.write("\n")
return wrapper
@catch_exceptions
def risky_function(x):
return 1 / x
risky_function(0) # 会被捕获
使用 atexit 模块处理程序退出时的异常
import atexit
import sys
def cleanup_handler():
"""程序退出时的清理处理"""
print("程序正在退出...")
# 检查是否有未处理的异常
if sys.exc_info()[0] is not None:
print(f"程序异常退出: {sys.exc_info()[1]}")
atexit.register(cleanup_handler)
# 生产环境中更好的方式:注册多个清理函数
@atexit.register
def another_cleanup():
print("执行另一个清理操作")
上下文管理器方式
class GlobalExceptionCatcher:
"""上下文管理器:在代码块中捕获所有异常"""
def __enter__(self):
self.old_excepthook = sys.excepthook
sys.excepthook = self.handler
return self
def __exit__(self, exc_type, exc_val, exc_tb):
sys.excepthook = self.old_excepthook
return False # 不抑制异常
@staticmethod
def handler(exc_type, exc_value, exc_traceback):
print(f"在上下文管理器中捕获: {exc_value}")
# 处理异常...
# 使用
with GlobalExceptionCatcher():
# 这里的异常会被捕获
raise ValueError("测试")
Web框架中的全局异常处理(以Flask为例)
from flask import Flask, jsonify
app = Flask(__name__)
@app.errorhandler(404)
def not_found(error):
return jsonify({"error": "资源不存在"}), 404
@app.errorhandler(500)
def internal_error(error):
return jsonify({"error": "服务器内部错误"}), 500
# 捕获所有未处理异常
@app.errorhandler(Exception)
def unhandled_exception(error):
app.logger.error(f'未处理异常: {error}')
return jsonify({"error": "未知错误"}), 500
综合实践:生产环境推荐的方案
import sys
import traceback
import logging
from datetime import datetime
# 配置日志
logging.basicConfig(
level=logging.ERROR,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('production_errors.log'),
logging.StreamHandler()
]
)
def production_exception_handler(exc_type, exc_value, exc_traceback):
"""生产环境全局异常处理器"""
# 记录到日志
logging.error(
"未捕获异常",
exc_info=(exc_type, exc_value, exc_traceback)
)
# 发送告警(示例)
send_alert(f"关键错误: {exc_value}")
# 保存崩溃信息
save_crash_report(exc_type, exc_value, exc_traceback)
# 程序退出
sys.exit(1)
def send_alert(message):
"""发送告警通知(示例)"""
print(f"发送告警: {message}")
def save_crash_report(exc_type, exc_value, exc_traceback):
"""保存崩溃报告"""
with open(f'crash_{datetime.now().strftime("%Y%m%d_%H%M%S")}.log', 'w') as f:
traceback.print_exception(exc_type, exc_value, exc_traceback, file=f)
# 设置全局处理器
sys.excepthook = production_exception_handler
# 测试
raise ValueError("测试生产环境异常处理")
注意事项
import signal
# 处理信号中断
def signal_handler(signum, frame):
print(f"收到信号 {signum}")
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler) # Ctrl+C
signal.signal(signal.SIGTERM, signal_handler) # 终止信号
# 主程序逻辑
if __name__ == "__main__":
try:
# 主要业务代码
raise RuntimeError("主要程序错误")
except Exception as e:
print(f"主程序捕获异常: {e}")
# 执行清理操作
cleanup()
最佳实践建议:
- 开发环境:使用
sys.excepthook记录详细追踪信息 - 生产环境:记录日志 + 发送告警
- 多线程程序:同时设置
threading.excepthook - Web应用:使用框架提供的异常处理机制
- 关键系统:考虑使用专业错误跟踪服务(如Sentry)
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播