如何让自定义异常处理器同时适配sys.excepthook与threading.excepthook
通用异常处理器适配sys.excepthook和threading.excepthook
问题背景
已实现适配sys.excepthook的自定义异常处理器,主线程中运行正常,但将其直接赋值给threading.excepthook后,线程内触发异常会报错:
TypeError: custom_err_handler() missing 2 required positional arguments: 'exc_value' and 'exc_traceback'
核心原因是两者参数格式不一致:
sys.excepthook调用时传入三个独立参数:exc_type, exc_value, exc_tracebackthreading.excepthook调用时传入一个参数对象,该对象包含exc_type, exc_value, exc_traceback三个属性
解决方案
以下两种方式均可实现主线程与子线程异常的统一处理:
方案1:修改原处理器兼容两种参数格式
调整自定义处理器,使其自动识别并适配两种参数输入:
import logging import sys import threading logger = logging.getLogger('my_logger') # 配置日志输出 handler_print = logging.StreamHandler() handler_print.setLevel(logging.DEBUG) logger.addHandler(handler_print) def custom_err_handler(*args): # 处理threading.excepthook的调用场景 if len(args) == 1 and hasattr(args[0], 'exc_type'): exc_info = (args[0].exc_type, args[0].exc_value, args[0].exc_traceback) # 处理sys.excepthook的调用场景 elif len(args) == 3: exc_info = args # 意外参数格式,回退到默认处理器 else: return sys.__excepthook__(*args) logger.critical("Custom error handler triggered:", exc_info=exc_info) # 同时绑定到两个excepthook sys.excepthook = custom_err_handler threading.excepthook = custom_err_handler # 测试主线程异常(取消注释可测试) # integer = 3 # print("Value is" + integer) # 测试线程内异常 class TestThread(threading.Thread): def run(self): integer = 3 print("Value is" + integer) test_thread = TestThread() test_thread.start()
方案2:编写适配层函数
保留原处理器逻辑不变,给threading.excepthook添加一层参数转换的适配函数:
import logging import sys import threading logger = logging.getLogger('my_logger') handler_print = logging.StreamHandler() handler_print.setLevel(logging.DEBUG) logger.addHandler(handler_print) # 原sys.excepthook兼容的处理器 def custom_err_handler(exc_type, exc_value, exc_traceback): logger.critical("Custom error handler triggered:", exc_info=(exc_type, exc_value, exc_traceback)) # 适配threading.excepthook的包装函数 def threading_err_adapter(args): custom_err_handler(args.exc_type, args.exc_value, args.exc_traceback) # 分别绑定处理器 sys.excepthook = custom_err_handler threading.excepthook = threading_err_adapter # 测试线程异常 class TestThread(threading.Thread): def run(self): integer = 3 print("Value is" + integer) test_thread = TestThread() test_thread.start()
内容的提问来源于stack exchange,提问作者fdamien12
相关产品推荐
相关产品推荐

