From dc57e7fcf9ce392fbb8b172675fadca04824e12a Mon Sep 17 00:00:00 2001 From: LuiKlee Date: Tue, 16 Dec 2025 14:34:03 +0800 Subject: [PATCH] =?UTF-8?q?fix(message=5Fhandler):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=98=B2=E5=BE=A1=E6=80=A7=E6=A3=80=E6=9F=A5=E4=BB=A5=E5=A4=84?= =?UTF-8?q?=E7=90=86=E7=A9=BA=E6=B6=88=E6=81=AF=E6=AE=B5=EF=BC=8C=E7=A1=AE?= =?UTF-8?q?=E4=BF=9D=E8=BF=94=E5=9B=9E=E5=8D=A0=E4=BD=8D=E7=AC=A6=E6=96=87?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### 根本原因 **消息构建失败链路:** 1. 视频下载失败(HTTP 400、超时或网络错误) 2. 视频处理器返回 `None`,导致消息段列表为空 3. MessageBuilder 尝试构建空消息,抛出 ValueError 4. 程序中断,无法继续处理其他消息 **关键问题点:** - 文件:`src/plugins/built_in/napcat_adapter/src/handlers/to_core/message_handler.py` - 当所有消息段都处理失败时,没有降级处理机制 - 视频处理的 4 个异常路径都返回 `None`,没有备选方案 **修改 1:视频处理失败降级处理** ```python # 原来:return None(导致消息为空) # 现在:return {"type": "text", "data": "[视频消息] (错误原因)"} 缺少 URL/文件路径 → [视频消息] 下载失败 → [视频消息] (下载失败) 处理异常 → [视频消息处理出错] 修改 2:消息构建前的防御检查 # 在 msg_builder.build() 之前 if not seg_list: logger.warning("消息内容为空,添加占位符文本") seg_list.append({"type": "text", "data": "[消息内容为空]"}) --- .../src/handlers/to_core/message_handler.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/plugins/built_in/napcat_adapter/src/handlers/to_core/message_handler.py b/src/plugins/built_in/napcat_adapter/src/handlers/to_core/message_handler.py index b2afa45a5..e2e8a6b85 100644 --- a/src/plugins/built_in/napcat_adapter/src/handlers/to_core/message_handler.py +++ b/src/plugins/built_in/napcat_adapter/src/handlers/to_core/message_handler.py @@ -105,6 +105,11 @@ class MessageHandler: if seg_message: seg_list.append(seg_message) + # 防御性检查:确保至少有一个消息段,避免消息为空导致构建失败 + if not seg_list: + logger.warning("消息内容为空,添加占位符文本") + seg_list.append({"type": "text", "data": "[消息内容为空]"}) + msg_builder.format_info( content_format=[seg["type"] for seg in seg_list], accept_format=ACCEPT_FORMAT, @@ -302,7 +307,7 @@ class MessageHandler: video_source = file_path if file_path else video_url if not video_source: logger.warning("视频消息缺少URL或文件路径信息") - return None + return {"type": "text", "data": "[视频消息]"} try: if file_path and Path(file_path).exists(): @@ -327,7 +332,7 @@ class MessageHandler: if not download_result["success"]: logger.warning(f"视频下载失败: {download_result.get('error', '未知错误')}") - return None + return {"type": "text", "data": f"[视频消息] ({download_result.get('error', '下载失败')})"} video_base64 = base64.b64encode(download_result["data"]).decode("utf-8") logger.debug(f"视频下载成功,大小: {len(download_result['data']) / (1024 * 1024):.2f} MB") @@ -343,11 +348,11 @@ class MessageHandler: } else: logger.warning("既没有有效的本地文件路径,也没有有效的视频URL") - return None + return {"type": "text", "data": "[视频消息]"} except Exception as e: logger.error(f"视频消息处理失败: {e!s}") - return None + return {"type": "text", "data": "[视频消息处理出错]"} async def _handle_rps_message(self, segment: dict) -> SegPayload: """处理猜拳消息"""