fix(mcp): surface per-app failures when importing MCP servers from apps

import_mcp_from_apps swallowed every importer error with unwrap_or(0),
so a corrupt config.toml surfaced as "imported 0 servers" with no hint
that anything went wrong.

Move the aggregation into McpService::import_from_all_apps: each app
imports best-effort (one bad file doesn't block the rest), and failures
are collected into a single error naming the failing apps alongside the
count that did import. The frontend now refreshes the server list on
settle rather than success, since a partial failure still means new
servers were persisted.
This commit is contained in:
Jason
2026-07-08 22:21:37 +08:00
parent 11c173c730
commit 94fc1cc064
4 changed files with 91 additions and 8 deletions
+1 -7
View File
@@ -197,11 +197,5 @@ pub async fn toggle_mcp_app(
/// 从所有应用导入 MCP 服务器(复用已有的导入逻辑)
#[tauri::command]
pub async fn import_mcp_from_apps(state: State<'_, AppState>) -> Result<usize, String> {
let mut total = 0;
total += McpService::import_from_claude(&state).unwrap_or(0);
total += McpService::import_from_codex(&state).unwrap_or(0);
total += McpService::import_from_gemini(&state).unwrap_or(0);
total += McpService::import_from_opencode(&state).unwrap_or(0);
total += McpService::import_from_hermes(&state).unwrap_or(0);
Ok(total)
McpService::import_from_all_apps(&state).map_err(|e| e.to_string())
}
+37
View File
@@ -468,4 +468,41 @@ impl McpService {
Ok(new_count)
}
/// 从所有支持 MCP 的应用导入服务器,返回新导入的数量。
///
/// Best-effort:单个应用导入失败(如坏 config.toml)不阻断其余应用;
/// 全部跑完后若有失败,聚合成一个错误上报——历史实现逐应用
/// `unwrap_or(0)` 吞错,坏文件只会表现为"导入成功 0 个",用户
/// 无从得知哪个应用出了问题。
pub fn import_from_all_apps(state: &AppState) -> Result<usize, AppError> {
let mut total = 0;
let mut failures: Vec<String> = Vec::new();
let results: [(&str, Result<usize, AppError>); 5] = [
("claude", Self::import_from_claude(state)),
("codex", Self::import_from_codex(state)),
("gemini", Self::import_from_gemini(state)),
("opencode", Self::import_from_opencode(state)),
("hermes", Self::import_from_hermes(state)),
];
for (app, result) in results {
match result {
Ok(count) => total += count,
Err(err) => {
log::warn!("从 {app} 导入 MCP 失败: {err}");
failures.push(format!("{app}: {err}"));
}
}
}
if failures.is_empty() {
Ok(total)
} else {
Err(AppError::Message(format!(
"已导入 {total} 个,部分应用导入失败: {}",
failures.join("; ")
)))
}
}
}