From 4c1df582ba540aaff4fc6913ed080c5e65099ac0 Mon Sep 17 00:00:00 2001 From: Tunglies <77394545+Tunglies@users.noreply.github.com> Date: Tue, 25 Aug 2026 19:48:48 +0800 Subject: [PATCH] fix(profile): propagate subscription update failures --- src-tauri/src/cmd/profile.rs | 2 +- src-tauri/src/core/timer.rs | 13 +------ src-tauri/src/feat/profile.rs | 68 ++++++++++++++++------------------- 3 files changed, 33 insertions(+), 50 deletions(-) diff --git a/src-tauri/src/cmd/profile.rs b/src-tauri/src/cmd/profile.rs index 3d8dbf3ff..a8f8df33f 100644 --- a/src-tauri/src/cmd/profile.rs +++ b/src-tauri/src/cmd/profile.rs @@ -133,7 +133,7 @@ pub async fn create_profile(item: PrfItem, file_data: Option) -> CmdResu #[tauri::command] pub async fn update_profile(index: String, option: Option) -> CmdResult { - match feat::update_profile(&index, option.as_ref(), true, true, true).await { + match feat::update_profile(&index, option.as_ref(), true).await { Ok(_) => Ok(()), Err(e) => { logging!(error, Type::Cmd, "{}", e); diff --git a/src-tauri/src/core/timer.rs b/src-tauri/src/core/timer.rs index cf647ac9c..a9a7edee4 100644 --- a/src-tauri/src/core/timer.rs +++ b/src-tauri/src/core/timer.rs @@ -472,18 +472,7 @@ impl Timer { run_timer_profile_update_transition( || Self::emit_update_event(uid, true), - || async { - let is_current = Config::profiles().await.latest_arc().current.as_ref() == Some(uid); - logging!( - debug, - Type::Timer, - "Profile {} is current active profile: {}", - uid, - is_current - ); - - feat::update_profile(uid, None, is_current, false, false).await - }, + || feat::update_profile(uid, None, false), |result| match result { Ok(_) => { logging!( diff --git a/src-tauri/src/feat/profile.rs b/src-tauri/src/feat/profile.rs index 4c0f8cd15..46233fda1 100644 --- a/src-tauri/src/feat/profile.rs +++ b/src-tauri/src/feat/profile.rs @@ -119,13 +119,9 @@ async fn perform_profile_update( opt: Option<&PrfOption>, option: Option<&PrfOption>, is_mannual_trigger: bool, -) -> Result { +) -> Result<()> { logging!(info, Type::Config, "[订阅更新] 开始下载新的订阅内容"); let mut merged_opt = PrfOption::merge(opt, option); - let is_current = { - let profiles = Config::profiles().await; - profiles.latest_arc().current.as_ref() == Some(uid) - }; let profiles = Config::profiles().await; let profiles_arc = profiles.latest_arc(); let profile_name = profiles_arc @@ -134,13 +130,11 @@ async fn perform_profile_update( .and_then(|item| item.name.clone()) .unwrap_or_else(|| String::from("UnKnown Profile")); - let mut last_err; - match PrfItem::from_url(url, None, None, merged_opt.as_ref()).await { Ok(mut item) => { logging!(info, Type::Config, "[订阅更新] 更新订阅配置成功"); profiles_update_item_safe(uid, &mut item).await?; - return Ok(is_current); + return Ok(()); } Err(err) => { logging!( @@ -149,7 +143,6 @@ async fn perform_profile_update( "Warning: [订阅更新] 正常更新失败: {},尝试使用Clash代理更新", mask_err(&err.to_string()) ); - last_err = err; } } @@ -161,8 +154,7 @@ async fn perform_profile_update( logging!(info, Type::Config, "[订阅更新] 使用 Clash代理 更新订阅配置成功"); profiles_update_item_safe(uid, &mut item).await?; handle::Handle::notice_message("update_with_clash_proxy", profile_name); - drop(last_err); - return Ok(is_current); + return Ok(()); } Err(err) => { logging!( @@ -171,20 +163,18 @@ async fn perform_profile_update( "Warning: [订阅更新] Clash代理更新失败: {},尝试使用系统代理更新", mask_err(&err.to_string()) ); - last_err = err; } } merged_opt.get_or_insert_with(PrfOption::default).self_proxy = Some(false); merged_opt.get_or_insert_with(PrfOption::default).with_proxy = Some(true); - match PrfItem::from_url(url, None, None, merged_opt.as_ref()).await { + let last_err = match PrfItem::from_url(url, None, None, merged_opt.as_ref()).await { Ok(mut item) => { logging!(info, Type::Config, "[订阅更新] 使用 系统代理 更新订阅配置成功"); profiles_update_item_safe(uid, &mut item).await?; handle::Handle::notice_message("update_with_clash_proxy", profile_name); - drop(last_err); - return Ok(is_current); + return Ok(()); } Err(err) => { logging!( @@ -193,32 +183,31 @@ async fn perform_profile_update( "Warning: [订阅更新] 系统代理更新失败: {},所有重试均已失败", mask_err(&err.to_string()) ); - last_err = err; + err } - } + }; + let last_err = mask_err(&last_err.to_string()); if is_mannual_trigger { handle::Handle::notice_message("update_failed_even_with_clash", format!("{profile_name} - {last_err}")); } - Ok(is_current) + bail!(last_err) } -pub async fn update_profile( - uid: &String, - option: Option<&PrfOption>, - auto_refresh: bool, - ignore_auto_update: bool, - is_mannual_trigger: bool, -) -> Result<()> { +pub async fn update_profile(uid: &String, option: Option<&PrfOption>, is_mannual_trigger: bool) -> Result<()> { logging!(info, Type::Config, "[订阅更新] 开始更新订阅 {}", uid); - let url_opt = should_update_profile(uid, ignore_auto_update).await?; + let url_opt = should_update_profile(uid, is_mannual_trigger).await?; - let should_refresh = match url_opt { + let profile_persisted = match url_opt { Some((url, opt)) => { - perform_profile_update(uid, &url, opt.as_ref(), option, is_mannual_trigger).await? && auto_refresh + perform_profile_update(uid, &url, opt.as_ref(), option, is_mannual_trigger).await?; + true } - None => auto_refresh, + None => false, }; + let profiles = Config::profiles().await; + let is_current = profiles.latest_arc().current.as_ref() == Some(uid); + let should_refresh = is_current || (!profile_persisted && is_mannual_trigger); if should_refresh { logging!(info, Type::Config, "[订阅更新] 更新内核配置"); @@ -230,15 +219,20 @@ pub async fn update_profile( Ok(outcome @ (ValidationOutcome::Skipped { .. } | ValidationOutcome::Busy)) if !is_mannual_trigger => { logging!(info, Type::Config, "[订阅更新] 本次配置刷新已跳过: {}", outcome); } - Ok(outcome) => { - let message = outcome.to_string(); + result => { + let message = match result { + Ok(outcome) => outcome.to_string(), + Err(err) => err.to_string(), + }; + let message = mask_err(&message); + let message = if profile_persisted { + format!("订阅已保存,但未能确认已应用到内核: {message}") + } else { + message + }; logging!(error, Type::Config, "[订阅更新] 更新失败: {}", message); - handle::Handle::notice_message("update_failed", message); - } - Err(err) => { - logging!(error, Type::Config, "[订阅更新] 更新失败: {}", err); - handle::Handle::notice_message("update_failed", format!("{err}")); - logging!(error, Type::Config, "{err}"); + handle::Handle::notice_message("update_failed", &message); + bail!(message); } } }