refactor(backend): replace unsafe unwrap calls with proper error handling

- Add to_json_string helper for safe JSON serialization
- Add lock_conn macro for safe Mutex locking
- Replace 41 unwrap() calls with proper error handling:
  - database.rs: JSON serialization and Mutex operations (31 fixes)
  - lib.rs: macOS NSWindow and tray icon handling (3 fixes)
  - services/provider.rs: Claude model normalization (1 fix)
  - services/prompt.rs: timestamp generation (3 fixes)
  - services/skill.rs: directory name extraction (2 fixes)
  - mcp.rs: HashMap initialization and type conversions (5 fixes)
  - app_config.rs: timestamp fallback (1 fix)

This improves application stability and prevents potential panics.
This commit is contained in:
YoVinchen
2025-11-23 16:23:18 +08:00
parent be1c2ac76e
commit 0cb8b30f15
7 changed files with 332 additions and 74 deletions

View File

@@ -348,10 +348,7 @@ pub fn import_from_claude(config: &mut MultiAppConfig) -> Result<usize, AppError
};
// 确保新结构存在
if config.mcp.servers.is_none() {
config.mcp.servers = Some(HashMap::new());
}
let servers = config.mcp.servers.as_mut().unwrap();
let servers = config.mcp.servers.get_or_insert_with(HashMap::new);
let mut changed = 0;
let mut errors = Vec::new();
@@ -421,10 +418,7 @@ pub fn import_from_codex(config: &mut MultiAppConfig) -> Result<usize, AppError>
.map_err(|e| AppError::McpValidation(format!("解析 ~/.codex/config.toml 失败: {e}")))?;
// 确保新结构存在
if config.mcp.servers.is_none() {
config.mcp.servers = Some(HashMap::new());
}
let servers = config.mcp.servers.as_mut().unwrap();
let servers = config.mcp.servers.get_or_insert_with(HashMap::new);
let mut changed_total = 0usize;
@@ -724,10 +718,7 @@ pub fn import_from_gemini(config: &mut MultiAppConfig) -> Result<usize, AppError
};
// 确保新结构存在
if config.mcp.servers.is_none() {
config.mcp.servers = Some(HashMap::new());
}
let servers = config.mcp.servers.as_mut().unwrap();
let servers = config.mcp.servers.get_or_insert_with(HashMap::new);
let mut changed = 0;
let mut errors = Vec::new();
@@ -852,8 +843,22 @@ fn json_value_to_toml_item(value: &Value, field_name: &str) -> Option<toml_edit:
for item in arr {
match item {
Value::String(s) => toml_arr.push(s.as_str()),
Value::Number(n) if n.is_i64() => toml_arr.push(n.as_i64().unwrap()),
Value::Number(n) if n.is_f64() => toml_arr.push(n.as_f64().unwrap()),
Value::Number(n) if n.is_i64() => {
if let Some(i) = n.as_i64() {
toml_arr.push(i);
} else {
all_same_type = false;
break;
}
}
Value::Number(n) if n.is_f64() => {
if let Some(f) = n.as_f64() {
toml_arr.push(f);
} else {
all_same_type = false;
break;
}
}
Value::Bool(b) => toml_arr.push(*b),
_ => {
all_same_type = false;