fix: guard app setup panics during startup

This commit is contained in:
wonfen
2026-07-01 11:51:22 +08:00
parent 9a2f4ff8fb
commit af0518d578
4 changed files with 72 additions and 38 deletions
Generated
+19 -19
View File
@@ -1226,8 +1226,8 @@ dependencies = [
[[package]]
name = "clash_verge_service_ipc"
version = "2.3.1"
source = "git+https://github.com/clash-verge-rev/clash-verge-service-ipc#ebb8fc017032e77a4e897f46a8934ffe51beecb4"
version = "2.3.2"
source = "git+https://github.com/clash-verge-rev/clash-verge-service-ipc#f877babab2a042bf01845e9b8879ca63dbb3b909"
dependencies = [
"anyhow",
"compact_str",
@@ -2005,7 +2005,7 @@ dependencies = [
"libc",
"option-ext",
"redox_users 0.5.2",
"windows-sys 0.61.2",
"windows-sys 0.59.0",
]
[[package]]
@@ -2276,7 +2276,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys 0.61.2",
"windows-sys 0.52.0",
]
[[package]]
@@ -3330,7 +3330,7 @@ dependencies = [
"libc",
"percent-encoding",
"pin-project-lite",
"socket2 0.6.4",
"socket2 0.5.10",
"system-configuration",
"tokio",
"tower-service",
@@ -4172,7 +4172,7 @@ dependencies = [
"png 0.18.1",
"serde",
"thiserror 2.0.18",
"windows-sys 0.61.2",
"windows-sys 0.60.2",
]
[[package]]
@@ -4339,7 +4339,7 @@ version = "0.50.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
dependencies = [
"windows-sys 0.61.2",
"windows-sys 0.59.0",
]
[[package]]
@@ -4760,7 +4760,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967"
dependencies = [
"libc",
"windows-sys 0.61.2",
"windows-sys 0.45.0",
]
[[package]]
@@ -5434,7 +5434,7 @@ dependencies = [
"quinn-udp",
"rustc-hash",
"rustls",
"socket2 0.6.4",
"socket2 0.5.10",
"thiserror 2.0.18",
"tokio",
"tracing",
@@ -5472,7 +5472,7 @@ dependencies = [
"cfg_aliases",
"libc",
"once_cell",
"socket2 0.6.4",
"socket2 0.5.10",
"tracing",
"windows-sys 0.60.2",
]
@@ -6021,7 +6021,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.12.1",
"windows-sys 0.61.2",
"windows-sys 0.52.0",
]
[[package]]
@@ -6080,7 +6080,7 @@ dependencies = [
"security-framework",
"security-framework-sys",
"webpki-root-certs",
"windows-sys 0.61.2",
"windows-sys 0.52.0",
]
[[package]]
@@ -6705,7 +6705,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51"
dependencies = [
"libc",
"windows-sys 0.61.2",
"windows-sys 0.60.2",
]
[[package]]
@@ -7586,10 +7586,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
dependencies = [
"fastrand",
"getrandom 0.4.3",
"getrandom 0.3.4",
"once_cell",
"rustix 1.1.4",
"windows-sys 0.61.2",
"windows-sys 0.52.0",
]
[[package]]
@@ -8309,7 +8309,7 @@ dependencies = [
"png 0.18.1",
"serde",
"thiserror 2.0.18",
"windows-sys 0.61.2",
"windows-sys 0.60.2",
]
[[package]]
@@ -8411,7 +8411,7 @@ checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e"
dependencies = [
"memoffset",
"tempfile",
"windows-sys 0.61.2",
"windows-sys 0.60.2",
]
[[package]]
@@ -8986,7 +8986,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
"windows-sys 0.61.2",
"windows-sys 0.48.0",
]
[[package]]
@@ -9579,7 +9579,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d6f32a0ff4a9f6f01231eb2059cc85479330739333e0e58cadf03b6af2cca10"
dependencies = [
"cfg-if",
"windows-sys 0.61.2",
"windows-sys 0.59.0",
]
[[package]]
+1 -1
View File
@@ -98,7 +98,7 @@ tauri-plugin-devtools = { version = "2.1.0" }
tauri-plugin-mihomo = { git = "https://github.com/clash-verge-rev/tauri-plugin-mihomo", branch = "fix/api-robustness" }
clash_verge_logger = { git = "https://github.com/clash-verge-rev/clash-verge-logger" }
async-trait = "0.1.89"
clash_verge_service_ipc = { version = "2.3.1", features = [
clash_verge_service_ipc = { version = "2.3.2", features = [
"client",
], git = "https://github.com/clash-verge-rev/clash-verge-service-ipc" }
arc-swap = "1.9.1"
+5 -1
View File
@@ -101,10 +101,14 @@ impl Logger {
*self.sidecar_file_writer.write() = Some(sidecar_file_writer);
std::panic::set_hook(Box::new(move |info| {
// Capture both common panic payload types instead of logging String payloads as unknown.
// This global hook covers panics after logger init; early setup panics are handled separately.
let payload = info
.payload()
.downcast_ref::<&str>()
.unwrap_or(&"Unknown panic payload");
.map(|s| (*s).to_string())
.or_else(|| info.payload().downcast_ref::<String>().cloned())
.unwrap_or_else(|| "Unknown panic payload".to_string());
let location = info
.location()
.map(|loc| format!("{}:{}", loc.file(), loc.line()))
+47 -17
View File
@@ -232,29 +232,59 @@ pub fn run() {
let builder = app_init::setup_plugins(tauri::Builder::default())
.setup(|app| {
#[allow(clippy::expect_used)]
APP_HANDLE
.set(app.app_handle().clone())
.expect("failed to set global app handle");
resolve::init_work_dir_and_logger()?;
logging!(info, Type::Setup, "开始应用初始化...");
if let Err(e) = app_init::setup_autostart(app) {
logging!(error, Type::Setup, "Failed to setup autostart: {}", e);
// Logger may not be ready yet, so mirror setup panics to stderr.
fn log_setup_panic(stage: &str, panic: Box<dyn std::any::Any + Send>) {
let msg = panic
.downcast_ref::<&str>()
.map(|s| (*s).to_string())
.or_else(|| panic.downcast_ref::<String>().cloned())
.unwrap_or_else(|| "unknown panic payload".to_string());
eprintln!("[clash-verge] panic during app setup ({stage}), continuing in degraded mode: {msg}");
logging!(
error,
Type::Setup,
"setup 阶段 panic({})—— 降级继续启动: {}",
stage,
msg
);
}
app_init::setup_deep_links(app);
// Prevent setup panics from aborting across macOS applicationDidFinishLaunching.
// Keep pre-init separate so window/core/tray startup is still scheduled after a panic.
if let Err(panic) = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
#[allow(clippy::expect_used)]
APP_HANDLE
.set(app.app_handle().clone())
.expect("failed to set global app handle");
if let Err(e) = app_init::setup_window_state(app) {
logging!(error, Type::Setup, "Failed to setup window state: {}", e);
if let Err(e) = resolve::init_work_dir_and_logger() {
logging!(error, Type::Setup, "Failed to init work dir/logger: {}", e);
}
logging!(info, Type::Setup, "开始应用初始化...");
if let Err(e) = app_init::setup_autostart(app) {
logging!(error, Type::Setup, "Failed to setup autostart: {}", e);
}
app_init::setup_deep_links(app);
if let Err(e) = app_init::setup_window_state(app) {
logging!(error, Type::Setup, "Failed to setup window state: {}", e);
}
})) {
log_setup_panic("pre-init", panic);
}
resolve::resolve_setup_async();
resolve::resolve_setup_sync();
resolve::init_signal();
// Always attempt the startup stage, even if pre-init degraded.
if let Err(panic) = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
resolve::resolve_setup_async();
resolve::resolve_setup_sync();
resolve::init_signal();
logging!(info, Type::Setup, "初始化已启动");
})) {
log_setup_panic("window-core", panic);
}
logging!(info, Type::Setup, "初始化已启动");
Ok(())
})
.invoke_handler(app_init::generate_handlers());