From c42a0dccaff4de165333c175109b328ba75a10d5 Mon Sep 17 00:00:00 2001 From: Jason Date: Fri, 12 Dec 2025 10:43:01 +0800 Subject: [PATCH] fix(proxy): auto-recover live config after abnormal exit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the app crashes or is force-killed while proxy mode is active, the live config files remain pointing to the dead proxy server with placeholder tokens, causing CLI tools to fail. This change adds startup detection: - Check `live_takeover_active` flag on app launch - If flag is true but proxy is not running → abnormal exit detected - Automatically restore live configs from database backup - Clear takeover flag and delete backups The recovery runs before auto-start, ensuring correct sequence even when proxy auto-start is enabled. --- src-tauri/src/lib.rs | 25 ++++++++++++++++++++++++- src-tauri/src/services/proxy.rs | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index e0faff175..f04dbfe14 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -522,10 +522,33 @@ pub fn run() { } } - // 自动启动代理服务器 + // 异常退出恢复 + 自动启动代理服务器 let app_handle = app.handle().clone(); tauri::async_runtime::spawn(async move { let state = app_handle.state::(); + + // 1. 检测异常退出并恢复 Live 配置 + match state.db.is_live_takeover_active().await { + Ok(true) => { + // 接管标志为 true 但代理未运行 → 上次异常退出 + if !state.proxy_service.is_running().await { + log::warn!("检测到上次异常退出,正在恢复 Live 配置..."); + if let Err(e) = state.proxy_service.recover_from_crash().await { + log::error!("恢复 Live 配置失败: {e}"); + } else { + log::info!("Live 配置已从异常退出中恢复"); + } + } + } + Ok(false) => { + // 正常状态,无需恢复 + } + Err(e) => { + log::error!("检查接管状态失败: {e}"); + } + } + + // 2. 自动启动代理服务器(如果配置为启用) match state.db.get_proxy_config().await { Ok(config) => { if config.enabled { diff --git a/src-tauri/src/services/proxy.rs b/src-tauri/src/services/proxy.rs index aff8bbc00..45d55f313 100644 --- a/src-tauri/src/services/proxy.rs +++ b/src-tauri/src/services/proxy.rs @@ -435,6 +435,30 @@ impl ProxyService { .map_err(|e| format!("检查接管状态失败: {e}")) } + /// 从异常退出中恢复(启动时调用) + /// + /// 检测到 live_takeover_active=true 但代理未运行时调用此方法。 + /// 会恢复 Live 配置、清除接管标志、删除备份。 + pub async fn recover_from_crash(&self) -> Result<(), String> { + // 1. 恢复 Live 配置 + self.restore_live_configs().await?; + + // 2. 清除接管标志 + self.db + .set_live_takeover_active(false) + .await + .map_err(|e| format!("清除接管状态失败: {e}"))?; + + // 3. 删除备份 + self.db + .delete_all_live_backups() + .await + .map_err(|e| format!("删除备份失败: {e}"))?; + + log::info!("已从异常退出中恢复 Live 配置"); + Ok(()) + } + /// 从供应商配置更新 Live 备份(用于代理模式下的热切换) /// /// 与 backup_live_configs() 不同,此方法从供应商的 settings_config 生成备份,