refactor(backend): complete phase 1 - full AppError migration (100%)

Finalized the backend error handling refactoring by migrating all remaining
modules to use AppError, eliminating all temporary error conversions.

## Changes

### Fully Migrated Modules

- **mcp.rs** (129 lines changed)
  - Migrated 13 functions from Result<T, String> to Result<T, AppError>
  - Added AppError::McpValidation for domain-specific validation errors
  - Functions: validate_server_spec, validate_mcp_entry, upsert_in_config_for,
    delete_in_config_for, set_enabled_and_sync_for, sync_enabled_to_claude,
    import_from_claude, import_from_codex, sync_enabled_to_codex
  - Removed all temporary error conversions

- **usage_script.rs** (143 lines changed)
  - Migrated 4 functions: execute_usage_script, send_http_request,
    validate_result, validate_single_usage
  - Used AppError::Message for JS runtime errors
  - Used AppError::InvalidInput for script validation errors
  - Improved error construction with ok_or_else (lazy evaluation)

- **lib.rs** (47 lines changed)
  - Migrated create_tray_menu() and switch_provider_internal()
  - Simplified PoisonError handling with AppError::from
  - Added error logging in update_tray_menu()
  - Improved error handling in menu update logic

- **migration.rs** (10 lines changed)
  - Migrated migrate_copies_into_config()
  - Used AppError::io() helper for file operations

- **speedtest.rs** (8 lines changed)
  - Migrated build_client() and test_endpoints()
  - Used AppError::Message for HTTP client errors

- **app_store.rs** (14 lines changed)
  - Migrated set_app_config_dir_to_store() and migrate_app_config_dir_from_settings()
  - Used AppError::Message for Tauri Store errors
  - Used AppError::io() for file system operations

### Fixed Previous Temporary Solutions

- **import_export.rs** (2 lines changed)
  - Removed AppError::Message wrapper for mcp::sync_enabled_to_codex
  - Now directly calls the AppError-returning function (no conversion needed)

- **commands.rs** (6 lines changed)
  - Updated query_provider_usage() and test_api_endpoints()
  - Explicit .to_string() conversion for Tauri command interface

## New Error Types

- **AppError::McpValidation**: Domain-specific error for MCP configuration validation
  - Separates MCP validation errors from generic Config errors
  - Follows domain-driven design principles

## Statistics

- Files changed: 8
- Lines changed: +237/-122 (net +115)
- Compilation:  Success (7.13s, 0 warnings)
- Tests:  4/4 passed

## Benefits

- **100% Migration**: All modules now use AppError consistently
- **Domain Errors**: Added McpValidation for better error categorization
- **No Temporary Solutions**: Eliminated all AppError::Message conversions for internal calls
- **Performance**: Used ok_or_else for lazy error construction
- **Maintainability**: Removed ~60 instances of .map_err(|e| format!("...", e))
- **Debugging**: Added error logging in critical paths (tray menu updates)

## Phase 1 Complete

Total impact across 3 commits:
- 25 files changed
- +671/-302 lines (net +369)
- 100% of codebase migrated from Result<T, String> to Result<T, AppError>
- 0 compilation warnings
- All tests passing

Ready for Phase 2: Splitting commands.rs by domain.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Jason
2025-10-27 20:36:08 +08:00
parent 1cc0e4bc8d
commit 4aa9512e36
8 changed files with 237 additions and 122 deletions

View File

@@ -3,6 +3,8 @@ use std::path::PathBuf;
use std::sync::{OnceLock, RwLock};
use tauri_plugin_store::StoreExt;
use crate::error::AppError;
/// Store 中的键名
const STORE_KEY_APP_CONFIG_DIR: &str = "app_config_dir_override";
@@ -75,11 +77,11 @@ pub fn get_app_config_dir_from_store(app: &tauri::AppHandle) -> Option<PathBuf>
pub fn set_app_config_dir_to_store(
app: &tauri::AppHandle,
path: Option<&str>,
) -> Result<(), String> {
) -> Result<(), AppError> {
let store = app
.store_builder("app_paths.json")
.build()
.map_err(|e| format!("创建 Store 失败: {}", e))?;
.map_err(|e| AppError::Message(format!("创建 Store 失败: {}", e)))?;
match path {
Some(p) => {
@@ -100,7 +102,9 @@ pub fn set_app_config_dir_to_store(
}
}
store.save().map_err(|e| format!("保存 Store 失败: {}", e))?;
store
.save()
.map_err(|e| AppError::Message(format!("保存 Store 失败: {}", e)))?;
Ok(())
}
@@ -125,7 +129,7 @@ fn resolve_path(raw: &str) -> PathBuf {
}
/// 从旧的 settings.json 迁移 app_config_dir 到 Store
pub fn migrate_app_config_dir_from_settings(app: &tauri::AppHandle) -> Result<(), String> {
pub fn migrate_app_config_dir_from_settings(app: &tauri::AppHandle) -> Result<(), AppError> {
// app_config_dir 已从 settings.json 移除,此函数保留但不再执行迁移
// 如果用户在旧版本设置过 app_config_dir需要在 Store 中手动配置
log::info!("app_config_dir 迁移功能已移除,请在设置中重新配置");
@@ -134,4 +138,4 @@ pub fn migrate_app_config_dir_from_settings(app: &tauri::AppHandle) -> Result<()
let _ = get_app_config_dir_from_store(app);
Ok(())
}
}