diff --git a/trading_system/main.py b/trading_system/main.py index 5d3a548..8e6a991 100644 --- a/trading_system/main.py +++ b/trading_system/main.py @@ -4,6 +4,7 @@ import asyncio import logging import sys +import traceback from pathlib import Path # 启动方式兼容(更鲁棒): @@ -119,8 +120,31 @@ except Exception: logger = logging.getLogger(__name__) +def _asyncio_exception_handler(loop, context): + """自定义 asyncio 异常处理器:将 WebSocket 关闭时的 ping 写入异常降级为 DEBUG,避免刷 ERROR。""" + exc = context.get("exception") + if exc is not None and isinstance(exc, ConnectionResetError): + msg = str(exc).lower() + if "closing transport" in msg or "cannot write" in msg: + logger.debug("WebSocket 连接关闭时 ping 已结束(可忽略): %s", exc) + return + # 其他「Task exception was never retrieved」按 asyncio 默认方式记录 + asyncio_logger = logging.getLogger("asyncio") + asyncio_logger.error("Task exception was never retrieved") + if "exception" in context: + asyncio_logger.error("".join(traceback.format_exception(context["exception"]))) + elif "message" in context: + asyncio_logger.error(context["message"]) + + async def main(): """主函数""" + # 设置 asyncio 未检索异常的处理器(避免 aiohttp WebSocket ping 在连接关闭时刷 ERROR) + try: + asyncio.get_running_loop().set_exception_handler(_asyncio_exception_handler) + except RuntimeError: + pass # 无运行中 loop 时忽略 + logger.info("=" * 60) logger.info("币安自动交易系统启动") logger.info("=" * 60)