2025-10-15 09:15:25 +08:00
use reqwest ::Client ;
2025-10-28 11:58:57 +08:00
use rquickjs ::{ Context , Function , Runtime } ;
2025-10-15 09:15:25 +08:00
use serde_json ::Value ;
use std ::collections ::HashMap ;
use std ::time ::Duration ;
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>
2025-10-27 20:36:08 +08:00
use crate ::error ::AppError ;
2025-10-15 09:15:25 +08:00
/// 执行用量查询脚本
pub async fn execute_usage_script (
script_code : & str ,
api_key : & str ,
base_url : & str ,
timeout_secs : u64 ,
2025-11-04 11:30:14 +08:00
access_token : Option < & str > ,
user_id : Option < & str > ,
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>
2025-10-27 20:36:08 +08:00
) -> Result < Value , AppError > {
2025-10-15 09:15:25 +08:00
// 1. 替换变量
2025-11-04 11:30:14 +08:00
let mut replaced = script_code
2025-10-15 09:15:25 +08:00
. replace ( " {{apiKey}} " , api_key )
. replace ( " {{baseUrl}} " , base_url ) ;
2025-11-04 11:30:14 +08:00
// 替换 accessToken 和 userId
if let Some ( token ) = access_token {
replaced = replaced . replace ( " {{accessToken}} " , token ) ;
}
if let Some ( uid ) = user_id {
replaced = replaced . replace ( " {{userId}} " , uid ) ;
}
2025-10-15 09:15:25 +08:00
// 2. 在独立作用域中提取 request 配置(确保 Runtime/Context 在 await 前释放)
let request_config = {
2025-10-28 11:58:57 +08:00
let runtime =
2025-11-05 00:07:54 +08:00
Runtime ::new ( ) . map_err ( | e | AppError ::localized ( " usage_script.runtime_create_failed " , format! ( " 创建 JS 运行时失败: {} " , e ) , format! ( " Failed to create JS runtime: {} " , e ) ) ) ? ;
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>
2025-10-27 20:36:08 +08:00
let context = Context ::full ( & runtime )
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.context_create_failed " , format! ( " 创建 JS 上下文失败: {} " , e ) , format! ( " Failed to create JS context: {} " , e ) ) ) ? ;
2025-10-15 09:15:25 +08:00
context . with ( | ctx | {
// 执行用户代码,获取配置对象
let config : rquickjs ::Object = ctx
. eval ( replaced . clone ( ) )
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.config_parse_failed " , format! ( " 解析配置失败: {} " , e ) , format! ( " Failed to parse config: {} " , e ) ) ) ? ;
2025-10-15 09:15:25 +08:00
// 提取 request 配置
let request : rquickjs ::Object = config
. get ( " request " )
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.request_missing " , format! ( " 缺少 request 配置: {} " , e ) , format! ( " Missing request config: {} " , e ) ) ) ? ;
2025-10-15 09:15:25 +08:00
// 将 request 转换为 JSON 字符串
let request_json : String = ctx
. json_stringify ( request )
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.request_serialize_failed " , format! ( " 序列化 request 失败: {} " , e ) , format! ( " Failed to serialize request: {} " , e ) ) ) ?
. ok_or_else ( | | AppError ::localized ( " usage_script.serialize_none " , " 序列化返回 None " , " Serialization returned None " ) ) ?
2025-10-15 09:15:25 +08:00
. get ( )
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.get_string_failed " , format! ( " 获取字符串失败: {} " , e ) , format! ( " Failed to get string: {} " , e ) ) ) ? ;
2025-10-15 09:15:25 +08:00
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>
2025-10-27 20:36:08 +08:00
Ok ::< _ , AppError > ( request_json )
2025-10-15 09:15:25 +08:00
} ) ?
} ; // Runtime 和 Context 在这里被 drop
// 3. 解析 request 配置
let request : RequestConfig = serde_json ::from_str ( & request_config )
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.request_format_invalid " , format! ( " request 配置格式错误: {} " , e ) , format! ( " Invalid request config format: {} " , e ) ) ) ? ;
2025-10-15 09:15:25 +08:00
// 4. 发送 HTTP 请求
let response_data = send_http_request ( & request , timeout_secs ) . await ? ;
// 5. 在独立作用域中执行 extractor( 确保 Runtime/Context 在函数结束前释放)
let result : Value = {
2025-10-28 11:58:57 +08:00
let runtime =
2025-11-05 00:07:54 +08:00
Runtime ::new ( ) . map_err ( | e | AppError ::localized ( " usage_script.runtime_create_failed " , format! ( " 创建 JS 运行时失败: {} " , e ) , format! ( " Failed to create JS runtime: {} " , e ) ) ) ? ;
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>
2025-10-27 20:36:08 +08:00
let context = Context ::full ( & runtime )
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.context_create_failed " , format! ( " 创建 JS 上下文失败: {} " , e ) , format! ( " Failed to create JS context: {} " , e ) ) ) ? ;
2025-10-15 09:15:25 +08:00
context . with ( | ctx | {
// 重新 eval 获取配置对象
let config : rquickjs ::Object = ctx
. eval ( replaced . clone ( ) )
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.config_reparse_failed " , format! ( " 重新解析配置失败: {} " , e ) , format! ( " Failed to re-parse config: {} " , e ) ) ) ? ;
2025-10-15 09:15:25 +08:00
// 提取 extractor 函数
let extractor : Function = config
. get ( " extractor " )
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.extractor_missing " , format! ( " 缺少 extractor 函数: {} " , e ) , format! ( " Missing extractor function: {} " , e ) ) ) ? ;
2025-10-15 09:15:25 +08:00
// 将响应数据转换为 JS 值
let response_js : rquickjs ::Value = ctx
. json_parse ( response_data . as_str ( ) )
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.response_parse_failed " , format! ( " 解析响应 JSON 失败: {} " , e ) , format! ( " Failed to parse response JSON: {} " , e ) ) ) ? ;
2025-10-15 09:15:25 +08:00
// 调用 extractor(response)
let result_js : rquickjs ::Value = extractor
. call ( ( response_js , ) )
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.extractor_exec_failed " , format! ( " 执行 extractor 失败: {} " , e ) , format! ( " Failed to execute extractor: {} " , e ) ) ) ? ;
2025-10-15 09:15:25 +08:00
// 转换为 JSON 字符串
let result_json : String = ctx
. json_stringify ( result_js )
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.result_serialize_failed " , format! ( " 序列化结果失败: {} " , e ) , format! ( " Failed to serialize result: {} " , e ) ) ) ?
. ok_or_else ( | | AppError ::localized ( " usage_script.serialize_none " , " 序列化返回 None " , " Serialization returned None " ) ) ?
2025-10-15 09:15:25 +08:00
. get ( )
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.get_string_failed " , format! ( " 获取字符串失败: {} " , e ) , format! ( " Failed to get string: {} " , e ) ) ) ? ;
2025-10-15 09:15:25 +08:00
// 解析为 serde_json::Value
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>
2025-10-27 20:36:08 +08:00
serde_json ::from_str ( & result_json )
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.json_parse_failed " , format! ( " JSON 解析失败: {} " , e ) , format! ( " JSON parse failed: {} " , e ) ) )
2025-10-15 09:15:25 +08:00
} ) ?
} ; // Runtime 和 Context 在这里被 drop
// 6. 验证返回值格式
validate_result ( & result ) ? ;
Ok ( result )
}
/// 请求配置结构
#[ derive(Debug, serde::Deserialize) ]
struct RequestConfig {
url : String ,
method : String ,
#[ serde(default) ]
headers : HashMap < String , String > ,
#[ serde(default) ]
body : Option < String > ,
}
/// 发送 HTTP 请求
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>
2025-10-27 20:36:08 +08:00
async fn send_http_request ( config : & RequestConfig , timeout_secs : u64 ) -> Result < String , AppError > {
2025-11-03 10:24:59 +08:00
// 约束超时范围,防止异常配置导致长时间阻塞
let timeout = timeout_secs . clamp ( 2 , 30 ) ;
2025-10-15 09:15:25 +08:00
let client = Client ::builder ( )
2025-11-03 10:24:59 +08:00
. timeout ( Duration ::from_secs ( timeout ) )
2025-10-15 09:15:25 +08:00
. build ( )
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.client_create_failed " , format! ( " 创建客户端失败: {} " , e ) , format! ( " Failed to create client: {} " , e ) ) ) ? ;
2025-10-15 09:15:25 +08:00
2025-11-03 10:24:59 +08:00
// 严格校验 HTTP 方法,非法值不回退为 GET
let method : reqwest ::Method = config
. method
. parse ( )
. map_err ( | _ | AppError ::InvalidHttpMethod ( config . method . clone ( ) ) ) ? ;
2025-10-15 09:15:25 +08:00
let mut req = client . request ( method . clone ( ) , & config . url ) ;
// 添加请求头
for ( k , v ) in & config . headers {
req = req . header ( k , v ) ;
}
// 添加请求体
if let Some ( body ) = & config . body {
req = req . body ( body . clone ( ) ) ;
}
// 发送请求
let resp = req
. send ( )
. await
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.request_failed " , format! ( " 请求失败: {} " , e ) , format! ( " Request failed: {} " , e ) ) ) ? ;
2025-10-15 09:15:25 +08:00
let status = resp . status ( ) ;
let text = resp
. text ( )
. await
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.read_response_failed " , format! ( " 读取响应失败: {} " , e ) , format! ( " Failed to read response: {} " , e ) ) ) ? ;
2025-10-15 09:15:25 +08:00
if ! status . is_success ( ) {
let preview = if text . len ( ) > 200 {
format! ( " {} ... " , & text [ .. 200 ] )
} else {
text . clone ( )
} ;
2025-11-05 00:07:54 +08:00
return Err ( AppError ::localized ( " usage_script.http_error " , format! ( " HTTP {} : {} " , status , preview ) , format! ( " HTTP {} : {} " , status , preview ) ) ) ;
2025-10-15 09:15:25 +08:00
}
Ok ( text )
}
/// 验证脚本返回值(支持单对象或数组)
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>
2025-10-27 20:36:08 +08:00
fn validate_result ( result : & Value ) -> Result < ( ) , AppError > {
2025-10-15 09:15:25 +08:00
// 如果是数组,验证每个元素
if let Some ( arr ) = result . as_array ( ) {
if arr . is_empty ( ) {
2025-11-05 00:07:54 +08:00
return Err ( AppError ::localized ( " usage_script.empty_array " , " 脚本返回的数组不能为空 " , " Script returned empty array " ) ) ;
2025-10-15 09:15:25 +08:00
}
for ( idx , item ) in arr . iter ( ) . enumerate ( ) {
validate_single_usage ( item )
2025-11-05 00:07:54 +08:00
. map_err ( | e | AppError ::localized ( " usage_script.array_validation_failed " , format! ( " 数组索引[ {} ]验证失败: {} " , idx , e ) , format! ( " Validation failed at index [ {} ]: {} " , idx , e ) ) ) ? ;
2025-10-15 09:15:25 +08:00
}
return Ok ( ( ) ) ;
}
// 如果是单对象,直接验证(向后兼容)
validate_single_usage ( result )
}
/// 验证单个用量数据对象
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>
2025-10-27 20:36:08 +08:00
fn validate_single_usage ( result : & Value ) -> Result < ( ) , AppError > {
2025-10-28 11:58:57 +08:00
let obj = result
. as_object ( )
2025-11-05 00:07:54 +08:00
. ok_or_else ( | | AppError ::localized ( " usage_script.must_return_object " , " 脚本必须返回对象或对象数组 " , " Script must return object or array of objects " ) ) ? ;
2025-10-15 09:15:25 +08:00
// 所有字段均为可选,只进行类型检查
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>
2025-10-27 20:36:08 +08:00
if obj . contains_key ( " isValid " )
& & ! result [ " isValid " ] . is_null ( )
& & ! result [ " isValid " ] . is_boolean ( )
{
2025-11-05 00:07:54 +08:00
return Err ( AppError ::localized ( " usage_script.isvalid_type_error " , " isValid 必须是布尔值或 null " , " isValid must be boolean or null " ) ) ;
2025-10-15 09:15:25 +08:00
}
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>
2025-10-27 20:36:08 +08:00
if obj . contains_key ( " invalidMessage " )
& & ! result [ " invalidMessage " ] . is_null ( )
& & ! result [ " invalidMessage " ] . is_string ( )
{
2025-11-05 00:07:54 +08:00
return Err ( AppError ::localized ( " usage_script.invalidmessage_type_error " , " invalidMessage 必须是字符串或 null " , " invalidMessage must be string or null " ) ) ;
2025-10-15 09:15:25 +08:00
}
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>
2025-10-27 20:36:08 +08:00
if obj . contains_key ( " remaining " )
& & ! result [ " remaining " ] . is_null ( )
& & ! result [ " remaining " ] . is_number ( )
{
2025-11-05 00:07:54 +08:00
return Err ( AppError ::localized ( " usage_script.remaining_type_error " , " remaining 必须是数字或 null " , " remaining must be number or null " ) ) ;
2025-10-15 09:15:25 +08:00
}
2025-10-28 11:58:57 +08:00
if obj . contains_key ( " unit " ) & & ! result [ " unit " ] . is_null ( ) & & ! result [ " unit " ] . is_string ( ) {
2025-11-05 00:07:54 +08:00
return Err ( AppError ::localized ( " usage_script.unit_type_error " , " unit 必须是字符串或 null " , " unit must be string or null " ) ) ;
2025-10-15 09:15:25 +08:00
}
2025-10-28 11:58:57 +08:00
if obj . contains_key ( " total " ) & & ! result [ " total " ] . is_null ( ) & & ! result [ " total " ] . is_number ( ) {
2025-11-05 00:07:54 +08:00
return Err ( AppError ::localized ( " usage_script.total_type_error " , " total 必须是数字或 null " , " total must be number or null " ) ) ;
2025-10-15 09:15:25 +08:00
}
2025-10-28 11:58:57 +08:00
if obj . contains_key ( " used " ) & & ! result [ " used " ] . is_null ( ) & & ! result [ " used " ] . is_number ( ) {
2025-11-05 00:07:54 +08:00
return Err ( AppError ::localized ( " usage_script.used_type_error " , " used 必须是数字或 null " , " used must be number or null " ) ) ;
2025-10-15 09:15:25 +08:00
}
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>
2025-10-27 20:36:08 +08:00
if obj . contains_key ( " planName " )
& & ! result [ " planName " ] . is_null ( )
& & ! result [ " planName " ] . is_string ( )
{
2025-11-05 00:07:54 +08:00
return Err ( AppError ::localized ( " usage_script.planname_type_error " , " planName 必须是字符串或 null " , " planName must be string or null " ) ) ;
2025-10-15 09:15:25 +08:00
}
2025-10-28 11:58:57 +08:00
if obj . contains_key ( " extra " ) & & ! result [ " extra " ] . is_null ( ) & & ! result [ " extra " ] . is_string ( ) {
2025-11-05 00:07:54 +08:00
return Err ( AppError ::localized ( " usage_script.extra_type_error " , " extra 必须是字符串或 null " , " extra must be string or null " ) ) ;
2025-10-15 09:15:25 +08:00
}
Ok ( ( ) )
}