mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 17:15:38 +08:00
fix: improve error handling and logging in various modules
This commit is contained in:
@@ -292,8 +292,7 @@ async fn restore_previous_profile(prev_profile: &String) -> CmdResult<()> {
|
|||||||
};
|
};
|
||||||
Config::profiles()
|
Config::profiles()
|
||||||
.await
|
.await
|
||||||
.edit_draft(|d| d.patch_config(&restore_profiles))
|
.edit_draft(|d| d.patch_config(&restore_profiles));
|
||||||
.stringify_err()?;
|
|
||||||
Config::profiles().await.apply();
|
Config::profiles().await.apply();
|
||||||
crate::process::AsyncHandler::spawn(|| async move {
|
crate::process::AsyncHandler::spawn(|| async move {
|
||||||
if let Err(e) = profiles_save_file_safe().await {
|
if let Err(e) = profiles_save_file_safe().await {
|
||||||
@@ -412,7 +411,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
|||||||
CURRENT_SWITCHING_PROFILE.store(false, Ordering::Release);
|
CURRENT_SWITCHING_PROFILE.store(false, Ordering::Release);
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
let _ = Config::profiles()
|
Config::profiles()
|
||||||
.await
|
.await
|
||||||
.edit_draft(|d| d.patch_config(&profiles));
|
.edit_draft(|d| d.patch_config(&profiles));
|
||||||
|
|
||||||
|
|||||||
@@ -155,15 +155,13 @@ impl Config {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let runtime = Config::runtime().await;
|
let runtime = Config::runtime().await;
|
||||||
let config = runtime
|
let runtime_arc = runtime.latest_arc();
|
||||||
.latest_arc()
|
let config = runtime_arc
|
||||||
.config
|
.config
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or_else(|| anyhow!("failed to get runtime config"))?
|
.ok_or_else(|| anyhow!("failed to get runtime config"))?;
|
||||||
.clone();
|
|
||||||
drop(runtime); // 显式释放锁
|
|
||||||
|
|
||||||
help::save_yaml(&path, &config, Some("# Generated by Clash Verge")).await?;
|
help::save_yaml(&path, config, Some("# Generated by Clash Verge")).await?;
|
||||||
Ok(path)
|
Ok(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ impl IProfiles {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 只修改current,valid和chain
|
/// 只修改current,valid和chain
|
||||||
pub fn patch_config(&mut self, patch: &IProfiles) -> Result<()> {
|
pub fn patch_config(&mut self, patch: &IProfiles) {
|
||||||
if self.items.is_none() {
|
if self.items.is_none() {
|
||||||
self.items = Some(vec![]);
|
self.items = Some(vec![]);
|
||||||
}
|
}
|
||||||
@@ -100,8 +100,6 @@ impl IProfiles {
|
|||||||
self.current = some_uid.cloned();
|
self.current = some_uid.cloned();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_current(&self) -> Option<&String> {
|
pub fn get_current(&self) -> Option<&String> {
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ use futures::future::join_all;
|
|||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use smartstring::alias::String;
|
use smartstring::alias::String;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::future::Future;
|
||||||
|
use std::pin::Pin;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{
|
use std::{
|
||||||
sync::atomic::{AtomicBool, Ordering},
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
@@ -575,9 +577,6 @@ impl Tray {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
use std::future::Future;
|
|
||||||
use std::pin::Pin;
|
|
||||||
|
|
||||||
let fut: Pin<Box<dyn Future<Output = ()> + Send>> = match tray_event.as_str() {
|
let fut: Pin<Box<dyn Future<Output = ()> + Send>> = match tray_event.as_str() {
|
||||||
"system_proxy" => Box::pin(async move {
|
"system_proxy" => Box::pin(async move {
|
||||||
feat::toggle_system_proxy().await;
|
feat::toggle_system_proxy().await;
|
||||||
@@ -1226,7 +1225,14 @@ fn on_menu_event(_: &AppHandle, event: MenuEvent) {
|
|||||||
};
|
};
|
||||||
feat::switch_proxy_node(group_name, proxy_name).await;
|
feat::switch_proxy_node(group_name, proxy_name).await;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {
|
||||||
|
logging!(
|
||||||
|
debug,
|
||||||
|
Type::Tray,
|
||||||
|
"Unhandled tray menu event: {:?}",
|
||||||
|
event.id
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We dont expected to refresh tray state here
|
// We dont expected to refresh tray state here
|
||||||
|
|||||||
@@ -275,41 +275,43 @@ impl CoreConfigValidator {
|
|||||||
logging!(info, Type::Validate, "验证目录: {}", app_dir_str);
|
logging!(info, Type::Validate, "验证目录: {}", app_dir_str);
|
||||||
|
|
||||||
// 使用子进程运行clash验证配置
|
// 使用子进程运行clash验证配置
|
||||||
let output = app_handle
|
let command = app_handle.shell().sidecar(clash_core.as_str())?.args([
|
||||||
.shell()
|
"-t",
|
||||||
.sidecar(clash_core.as_str())?
|
"-d",
|
||||||
.args(["-t", "-d", app_dir_str, "-f", config_path])
|
app_dir_str,
|
||||||
.output()
|
"-f",
|
||||||
.await?;
|
config_path,
|
||||||
|
]);
|
||||||
|
let output = command.output().await?;
|
||||||
|
|
||||||
let stderr = std::string::String::from_utf8_lossy(&output.stderr);
|
let status = &output.status;
|
||||||
let stdout = std::string::String::from_utf8_lossy(&output.stdout);
|
let stderr = &output.stderr;
|
||||||
|
let stdout = &output.stdout;
|
||||||
|
|
||||||
// 检查进程退出状态和错误输出
|
// 检查进程退出状态和错误输出
|
||||||
let error_keywords = ["FATA", "fatal", "Parse config error", "level=fatal"];
|
let error_keywords = ["FATA", "fatal", "Parse config error", "level=fatal"];
|
||||||
let has_error =
|
let has_error = !status.success() || contains_any_keyword(stderr, &error_keywords);
|
||||||
!output.status.success() || error_keywords.iter().any(|&kw| stderr.contains(kw));
|
|
||||||
|
|
||||||
logging!(info, Type::Validate, "-------- 验证结果 --------");
|
logging!(info, Type::Validate, "-------- 验证结果 --------");
|
||||||
|
|
||||||
if !stderr.is_empty() {
|
if !stderr.is_empty() {
|
||||||
logging!(info, Type::Validate, "stderr输出:\n{}", stderr);
|
logging!(info, Type::Validate, "stderr输出:\n{:?}", stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if has_error {
|
if has_error {
|
||||||
logging!(info, Type::Validate, "发现错误,开始处理错误信息");
|
logging!(info, Type::Validate, "发现错误,开始处理错误信息");
|
||||||
let error_msg = if !stdout.is_empty() {
|
let error_msg: String = if !stdout.is_empty() {
|
||||||
stdout.into()
|
str::from_utf8(stdout).unwrap_or_default().into()
|
||||||
} else if !stderr.is_empty() {
|
} else if !stderr.is_empty() {
|
||||||
stderr.into()
|
str::from_utf8(stderr).unwrap_or_default().into()
|
||||||
} else if let Some(code) = output.status.code() {
|
} else if let Some(code) = status.code() {
|
||||||
format!("验证进程异常退出,退出码: {code}")
|
format!("验证进程异常退出,退出码: {code}").into()
|
||||||
} else {
|
} else {
|
||||||
"验证进程被终止".into()
|
"验证进程被终止".into()
|
||||||
};
|
};
|
||||||
|
|
||||||
logging!(info, Type::Validate, "-------- 验证结束 --------");
|
logging!(info, Type::Validate, "-------- 验证结束 --------");
|
||||||
Ok((false, error_msg.into())) // 返回错误消息给调用者处理
|
Ok((false, error_msg)) // 返回错误消息给调用者处理
|
||||||
} else {
|
} else {
|
||||||
logging!(info, Type::Validate, "验证成功");
|
logging!(info, Type::Validate, "验证成功");
|
||||||
logging!(info, Type::Validate, "-------- 验证结束 --------");
|
logging!(info, Type::Validate, "-------- 验证结束 --------");
|
||||||
@@ -342,6 +344,23 @@ fn has_ext<P: AsRef<std::path::Path>>(path: P, ext: &str) -> bool {
|
|||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn contains_any_keyword<'a>(buf: &'a [u8], keywords: &'a [&str]) -> bool {
|
||||||
|
for &kw in keywords {
|
||||||
|
let needle = kw.as_bytes();
|
||||||
|
if needle.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let mut i = 0;
|
||||||
|
while i + needle.len() <= buf.len() {
|
||||||
|
if &buf[i..i + needle.len()] == needle {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
singleton_lazy!(
|
singleton_lazy!(
|
||||||
CoreConfigValidator,
|
CoreConfigValidator,
|
||||||
CORECONFIGVALIDATOR,
|
CORECONFIGVALIDATOR,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#[cfg(not(feature = "tracing"))]
|
// #[cfg(not(feature = "tracing"))]
|
||||||
#[cfg(not(feature = "tauri-dev"))]
|
#[cfg(not(feature = "tauri-dev"))]
|
||||||
use crate::utils::logging::NoModuleFilter;
|
use crate::utils::logging::NoModuleFilter;
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -49,7 +49,9 @@ pub async fn init_logger() -> Result<()> {
|
|||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
spec.module("tauri", log::LevelFilter::Debug);
|
spec.module("tauri", log::LevelFilter::Debug);
|
||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
spec.module("wry", log::LevelFilter::Debug);
|
spec.module("wry", log::LevelFilter::Off);
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
spec.module("tauri_plugin_mihomo", log::LevelFilter::Off);
|
||||||
let spec = spec.build();
|
let spec = spec.build();
|
||||||
|
|
||||||
let logger = Logger::with(spec)
|
let logger = Logger::with(spec)
|
||||||
@@ -67,6 +69,12 @@ pub async fn init_logger() -> Result<()> {
|
|||||||
);
|
);
|
||||||
#[cfg(not(feature = "tracing"))]
|
#[cfg(not(feature = "tracing"))]
|
||||||
let logger = logger.filter(Box::new(NoModuleFilter(&["wry", "tauri"])));
|
let logger = logger.filter(Box::new(NoModuleFilter(&["wry", "tauri"])));
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
let logger = logger.filter(Box::new(NoModuleFilter(&[
|
||||||
|
"wry",
|
||||||
|
"tauri_plugin_mihomo",
|
||||||
|
"kode_bridge",
|
||||||
|
])));
|
||||||
|
|
||||||
let _handle = logger.start()?;
|
let _handle = logger.start()?;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user