修复: unwrap 吞错 + lock 中毒 panic 高危项(数据吞 warn 跳过 / lock 降级返 Err)
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user