修复: unwrap 吞错 + lock 中毒 panic 高危项(数据吞 warn 跳过 / lock 降级返 Err)

This commit is contained in:
lxy
2026-08-01 12:21:52 +08:00
parent 143b859727
commit 484080ac12
6 changed files with 184 additions and 27 deletions
+26 -2
View File
@@ -585,8 +585,20 @@ async fn extract_knowledge_from_conversation(
.unwrap_or_else(|| "未命名对话".to_string());
// 消息读取:优先 ai_messages 表(消息拆分存储真相源),表空时 fallback 旧 messages JSON 列(老库兼容)
// 注意:DB 查询 Err 不能吞成空 Vec(否则 records.is_empty() 误为真 → 走旧 messages JSON 回退,
// 语义错:本应报 DB 故障)。这里显式 match:Ok 正常流程,Err 记 warn 后跳过本轮知识抽取。
let msg_repo = AiMessageRepo::new(db);
let records = msg_repo.list_by_conversation(conv_id).await.unwrap_or_default();
let records = match msg_repo.list_by_conversation(conv_id).await {
Ok(records) => records,
Err(e) => {
tracing::warn!(
error = %e,
conv_id,
"[KNOWLEDGE-EXTRACT] list_by_conversation 失败,跳过本轮知识抽取"
);
return Ok(0); // DB 故障,不当空数据回退(0 条,不置去重标志,允许下次重试)
}
};
let messages: Vec<ChatMessage> = if !records.is_empty() {
records.iter().map(crate::commands::ai::commands::record_to_message).collect()
} else {
@@ -598,7 +610,19 @@ async fn extract_knowledge_from_conversation(
"[KNOWLEDGE-EXTRACT] ai_messages 表为空,回退旧 messages JSON 列(老库兼容)"
);
}
serde_json::from_str(&conv.messages).unwrap_or_default()
// 损坏 → match Err 分流:勿 unwrap_or_default 吞成空 Vec(空 Vec 会让 knowledge 抽取基于空上下文,
// 误产空知识)。坏数据 warn 后跳过本轮(0 条,不置去重标志,允许下次重试),与 DB 故障同语义。
match serde_json::from_str::<Vec<ChatMessage>>(&conv.messages) {
Ok(v) => v,
Err(e) => {
tracing::warn!(
error = %e,
conv_id,
"[KNOWLEDGE-EXTRACT] 旧 messages JSON 列解析失败,跳过本轮知识抽取(勿基于空上下文抽取)"
);
return Ok(0);
}
}
};
// 过滤 user/assistant,取最后 6 条
let recent: Vec<&ChatMessage> = messages