mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-10-15 05:40:47 +08:00
fix(profile): propagate subscription update failures
This commit is contained in:
@@ -133,7 +133,7 @@ pub async fn create_profile(item: PrfItem, file_data: Option<String>) -> CmdResu
|
|||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn update_profile(index: String, option: Option<PrfOption>) -> CmdResult {
|
pub async fn update_profile(index: String, option: Option<PrfOption>) -> 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(()),
|
Ok(_) => Ok(()),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
logging!(error, Type::Cmd, "{}", e);
|
logging!(error, Type::Cmd, "{}", e);
|
||||||
|
|||||||
@@ -472,18 +472,7 @@ impl Timer {
|
|||||||
|
|
||||||
run_timer_profile_update_transition(
|
run_timer_profile_update_transition(
|
||||||
|| Self::emit_update_event(uid, true),
|
|| Self::emit_update_event(uid, true),
|
||||||
|| async {
|
|| feat::update_profile(uid, None, false),
|
||||||
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
|
|
||||||
},
|
|
||||||
|result| match result {
|
|result| match result {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
logging!(
|
logging!(
|
||||||
|
|||||||
@@ -119,13 +119,9 @@ async fn perform_profile_update(
|
|||||||
opt: Option<&PrfOption>,
|
opt: Option<&PrfOption>,
|
||||||
option: Option<&PrfOption>,
|
option: Option<&PrfOption>,
|
||||||
is_mannual_trigger: bool,
|
is_mannual_trigger: bool,
|
||||||
) -> Result<bool> {
|
) -> Result<()> {
|
||||||
logging!(info, Type::Config, "[订阅更新] 开始下载新的订阅内容");
|
logging!(info, Type::Config, "[订阅更新] 开始下载新的订阅内容");
|
||||||
let mut merged_opt = PrfOption::merge(opt, option);
|
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 = Config::profiles().await;
|
||||||
let profiles_arc = profiles.latest_arc();
|
let profiles_arc = profiles.latest_arc();
|
||||||
let profile_name = profiles_arc
|
let profile_name = profiles_arc
|
||||||
@@ -134,13 +130,11 @@ async fn perform_profile_update(
|
|||||||
.and_then(|item| item.name.clone())
|
.and_then(|item| item.name.clone())
|
||||||
.unwrap_or_else(|| String::from("UnKnown Profile"));
|
.unwrap_or_else(|| String::from("UnKnown Profile"));
|
||||||
|
|
||||||
let mut last_err;
|
|
||||||
|
|
||||||
match PrfItem::from_url(url, None, None, merged_opt.as_ref()).await {
|
match PrfItem::from_url(url, None, None, merged_opt.as_ref()).await {
|
||||||
Ok(mut item) => {
|
Ok(mut item) => {
|
||||||
logging!(info, Type::Config, "[订阅更新] 更新订阅配置成功");
|
logging!(info, Type::Config, "[订阅更新] 更新订阅配置成功");
|
||||||
profiles_update_item_safe(uid, &mut item).await?;
|
profiles_update_item_safe(uid, &mut item).await?;
|
||||||
return Ok(is_current);
|
return Ok(());
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
logging!(
|
logging!(
|
||||||
@@ -149,7 +143,6 @@ async fn perform_profile_update(
|
|||||||
"Warning: [订阅更新] 正常更新失败: {},尝试使用Clash代理更新",
|
"Warning: [订阅更新] 正常更新失败: {},尝试使用Clash代理更新",
|
||||||
mask_err(&err.to_string())
|
mask_err(&err.to_string())
|
||||||
);
|
);
|
||||||
last_err = err;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,8 +154,7 @@ async fn perform_profile_update(
|
|||||||
logging!(info, Type::Config, "[订阅更新] 使用 Clash代理 更新订阅配置成功");
|
logging!(info, Type::Config, "[订阅更新] 使用 Clash代理 更新订阅配置成功");
|
||||||
profiles_update_item_safe(uid, &mut item).await?;
|
profiles_update_item_safe(uid, &mut item).await?;
|
||||||
handle::Handle::notice_message("update_with_clash_proxy", profile_name);
|
handle::Handle::notice_message("update_with_clash_proxy", profile_name);
|
||||||
drop(last_err);
|
return Ok(());
|
||||||
return Ok(is_current);
|
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
logging!(
|
logging!(
|
||||||
@@ -171,20 +163,18 @@ async fn perform_profile_update(
|
|||||||
"Warning: [订阅更新] Clash代理更新失败: {},尝试使用系统代理更新",
|
"Warning: [订阅更新] Clash代理更新失败: {},尝试使用系统代理更新",
|
||||||
mask_err(&err.to_string())
|
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).self_proxy = Some(false);
|
||||||
merged_opt.get_or_insert_with(PrfOption::default).with_proxy = Some(true);
|
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) => {
|
Ok(mut item) => {
|
||||||
logging!(info, Type::Config, "[订阅更新] 使用 系统代理 更新订阅配置成功");
|
logging!(info, Type::Config, "[订阅更新] 使用 系统代理 更新订阅配置成功");
|
||||||
profiles_update_item_safe(uid, &mut item).await?;
|
profiles_update_item_safe(uid, &mut item).await?;
|
||||||
handle::Handle::notice_message("update_with_clash_proxy", profile_name);
|
handle::Handle::notice_message("update_with_clash_proxy", profile_name);
|
||||||
drop(last_err);
|
return Ok(());
|
||||||
return Ok(is_current);
|
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
logging!(
|
logging!(
|
||||||
@@ -193,32 +183,31 @@ async fn perform_profile_update(
|
|||||||
"Warning: [订阅更新] 系统代理更新失败: {},所有重试均已失败",
|
"Warning: [订阅更新] 系统代理更新失败: {},所有重试均已失败",
|
||||||
mask_err(&err.to_string())
|
mask_err(&err.to_string())
|
||||||
);
|
);
|
||||||
last_err = err;
|
err
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
let last_err = mask_err(&last_err.to_string());
|
||||||
if is_mannual_trigger {
|
if is_mannual_trigger {
|
||||||
handle::Handle::notice_message("update_failed_even_with_clash", format!("{profile_name} - {last_err}"));
|
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(
|
pub async fn update_profile(uid: &String, option: Option<&PrfOption>, is_mannual_trigger: bool) -> Result<()> {
|
||||||
uid: &String,
|
|
||||||
option: Option<&PrfOption>,
|
|
||||||
auto_refresh: bool,
|
|
||||||
ignore_auto_update: bool,
|
|
||||||
is_mannual_trigger: bool,
|
|
||||||
) -> Result<()> {
|
|
||||||
logging!(info, Type::Config, "[订阅更新] 开始更新订阅 {}", uid);
|
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)) => {
|
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 {
|
if should_refresh {
|
||||||
logging!(info, Type::Config, "[订阅更新] 更新内核配置");
|
logging!(info, Type::Config, "[订阅更新] 更新内核配置");
|
||||||
@@ -230,15 +219,20 @@ pub async fn update_profile(
|
|||||||
Ok(outcome @ (ValidationOutcome::Skipped { .. } | ValidationOutcome::Busy)) if !is_mannual_trigger => {
|
Ok(outcome @ (ValidationOutcome::Skipped { .. } | ValidationOutcome::Busy)) if !is_mannual_trigger => {
|
||||||
logging!(info, Type::Config, "[订阅更新] 本次配置刷新已跳过: {}", outcome);
|
logging!(info, Type::Config, "[订阅更新] 本次配置刷新已跳过: {}", outcome);
|
||||||
}
|
}
|
||||||
Ok(outcome) => {
|
result => {
|
||||||
let message = outcome.to_string();
|
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);
|
logging!(error, Type::Config, "[订阅更新] 更新失败: {}", message);
|
||||||
handle::Handle::notice_message("update_failed", message);
|
handle::Handle::notice_message("update_failed", &message);
|
||||||
}
|
bail!(message);
|
||||||
Err(err) => {
|
|
||||||
logging!(error, Type::Config, "[订阅更新] 更新失败: {}", err);
|
|
||||||
handle::Handle::notice_message("update_failed", format!("{err}"));
|
|
||||||
logging!(error, Type::Config, "{err}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user