diff --git a/Cargo.lock b/Cargo.lock index f3167d63..7df0e640 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3026,6 +3026,7 @@ dependencies = [ "Inflector", "alacritty_terminal", "anyhow", + "backtrace", "base64", "bytemuck", "chrono", @@ -3077,6 +3078,7 @@ dependencies = [ "tracing-subscriber", "unicode-width", "url", + "windows-sys 0.48.0", "zip", ] diff --git a/Cargo.toml b/Cargo.toml index 6ec896fd..d78bf8c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ authors = ["Dongdong Zhou "] [workspace.dependencies] anyhow = "1.0" +backtrace = "0.3" chrono = "0.4" clap = { version = "3.2.25", features = ["derive"] } crossbeam-channel = "0.5.8" @@ -98,6 +99,10 @@ package = "tracing-appender" git = "https://github.com/alacritty/alacritty" rev = "6071a7bf35cfd99be8ba70f479f188b7370cda6f" +[workspace.dependencies.windows-sys] +version = "0" +features = ["Win32_Foundation"] + [profile.release-lto] inherits = "release" lto = true diff --git a/lapce-app/Cargo.toml b/lapce-app/Cargo.toml index 66604b7f..e3fd82e2 100644 --- a/lapce-app/Cargo.toml +++ b/lapce-app/Cargo.toml @@ -7,6 +7,7 @@ edition.workspace = true [dependencies] alacritty_terminal.workspace = true anyhow.workspace = true +backtrace.workspace = true chrono.workspace = true clap.workspace = true crossbeam-channel.workspace = true @@ -66,6 +67,14 @@ globset = "0.4.9" fs_extra = "1.2.0" dmg = "0.1.1" +[target.'cfg(windows)'.dependencies.windows-sys] +workspace = true +features = [ + "Win32_Foundation", + "Win32_System_Threading", + "Win32_UI_WindowsAndMessaging", +] + [features] default = ["all-languages", "updater"] portable = ["lapce-core/portable"] diff --git a/lapce-app/src/app.rs b/lapce-app/src/app.rs index f4c64e69..ff9a7095 100644 --- a/lapce-app/src/app.rs +++ b/lapce-app/src/app.rs @@ -3373,6 +3373,8 @@ pub fn launch() { let (reload_handle, _guard) = logging(); tracing::info!("Starting up Lapce.."); + panic_hook(); + // if PWD is not set, then we are not being launched via a terminal #[cfg(any(target_os = "macos", target_os = "linux"))] if std::env::var("PWD").is_err() { @@ -3419,7 +3421,16 @@ pub fn launch() { crate::update::cleanup(); let _ = lapce_proxy::register_lapce_path(); - let db = Arc::new(LapceDb::new().unwrap()); + let db = match LapceDb::new() { + Ok(db) => Arc::new(db), + Err(e) => { + #[cfg(windows)] + error_modal("Error", &format!("Failed to create LapceDb: {e}")); + #[cfg(not(windows))] + error!("Failed to create LapceDb: {e}"); + std::process::exit(1); + } + }; let scope = Scope::new(); provide_context(db.clone()); @@ -3737,6 +3748,74 @@ pub fn window_menu( ) } +fn panic_hook() { + std::panic::set_hook(Box::new(move |info| { + let thread = std::thread::current(); + let thread = thread.name().unwrap_or("main"); + let backtrace = backtrace::Backtrace::new(); + + let payload = if let Some(s) = info.payload().downcast_ref::<&str>() { + s + } else { + "" + }; + + match info.location() { + Some(loc) => { + error!( + target: "lapce_app::panic_hook", + "thread {thread} panicked at {} | file://./{}:{}:{}\n{:?}", + payload, + loc.file(), loc.line(), loc.column(), + backtrace, + ); + } + None => { + error!( + target: "lapce_app::panic_hook", + "thread {thread} panicked at {}\n{:?}", + payload, + backtrace, + ); + } + } + + #[cfg(windows)] + error_modal("Error", &info.to_string()); + })) +} + +#[cfg(windows)] +fn error_modal(title: &str, msg: &str) -> i32 { + use std::iter::once; + use std::os::windows::prelude::OsStrExt; + use std::{ffi::OsStr, mem}; + use windows::Win32::UI::WindowsAndMessaging::{ + MessageBoxW, MB_ICONERROR, MB_SYSTEMMODAL, + }; + + let result: i32; + + let title = OsStr::new(title) + .encode_wide() + .chain(once(0u16)) + .collect::>(); + let msg = OsStr::new(msg) + .encode_wide() + .chain(once(0u16)) + .collect::>(); + unsafe { + result = MessageBoxW( + mem::zeroed(), + msg.as_ptr(), + title.as_ptr(), + MB_ICONERROR | MB_SYSTEMMODAL, + ); + } + + result +} + fn fetch_grammars() -> Result<()> { let dir = Directory::grammars_directory() .ok_or_else(|| anyhow!("can't get grammars directory"))?; diff --git a/lapce-app/src/lib.rs b/lapce-app/src/lib.rs index bbf8b621..99e81946 100644 --- a/lapce-app/src/lib.rs +++ b/lapce-app/src/lib.rs @@ -42,3 +42,6 @@ pub mod window; pub mod window_tab; pub mod workspace; + +#[cfg(windows)] +extern crate windows_sys as windows;