diff --git a/ctru-rs/src/applets/error.rs b/ctru-rs/src/applets/error.rs index 92dc7e3..67665ab 100644 --- a/ctru-rs/src/applets/error.rs +++ b/ctru-rs/src/applets/error.rs @@ -88,17 +88,21 @@ impl PopUp { } } -/// Sets a custom panic hook that uses the error applet to display panic messages. You can also choose to have -/// messages printed over stderr along with the pop-up display. +/// Sets a custom panic hook that uses the error applet to display panic messages. You can also choose to have the +/// default panic hook called to print the message over stderr. /// -/// If the `Gfx` service is not initialized during a panic, the error applet will not be displayed and the panic -/// message will be printed over stderr. -pub fn set_panic_hook(use_stderr: bool) { +/// If the `Gfx` service is not initialized during a panic, the error applet will not be displayed and the default +/// hook will be called. +pub fn set_panic_hook(call_default_hook: bool) { use crate::services::gfx::GFX_ACTIVE; - - use std::io::Write; use std::sync::TryLockError; + // Ensure we get the default hook instead of a previously registered user hook. + let default_hook = { + let _ = std::panic::take_hook(); + std::panic::take_hook() + }; + std::panic::set_hook(Box::new(move |panic_info| { let thread = std::thread::current(); @@ -107,8 +111,8 @@ pub fn set_panic_hook(use_stderr: bool) { // If we get a `WouldBlock` error, we know that the `Gfx` service has been initialized. // Otherwise fallback to printing over stderr. if let (Err(TryLockError::WouldBlock), Ok(_apt)) = (GFX_ACTIVE.try_lock(), Apt::new()) { - if use_stderr { - print_to_stderr(name, panic_info); + if call_default_hook { + default_hook(panic_info); } let payload = format!("thread '{name}' {panic_info}"); @@ -121,15 +125,9 @@ pub fn set_panic_hook(use_stderr: bool) { popup.launch_unchecked(); } } else { - print_to_stderr(name, panic_info); + default_hook(panic_info); } })); - - fn print_to_stderr(name: &str, panic_info: &std::panic::PanicInfo) { - let mut stderr = std::io::stderr().lock(); - - let _ = writeln!(stderr, "thread '{name}' {panic_info}"); - } } impl std::fmt::Display for Error {