fix(message_handler): 添加防御性检查以处理空消息段,确保返回占位符文本
### 根本原因
**消息构建失败链路:**
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": "[消息内容为空]"})
This commit is contained in:
@@ -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:
|
||||
"""处理猜拳消息"""
|
||||
|
||||
Reference in New Issue
Block a user