feat: Try log panics before unwinds to catch backtraces

This commit is contained in:
Jade Ellis 2026-02-05 16:44:51 +00:00 committed by Ellis Git
parent f243b383cb
commit f6df44b13f
2 changed files with 37 additions and 0 deletions

View file

@ -7,6 +7,7 @@ use conduwuit_core::{debug_info, error};
mod clap;
mod logging;
mod mods;
mod panic;
mod restart;
mod runtime;
mod sentry;
@ -19,6 +20,8 @@ use server::Server;
pub use crate::clap::Args;
pub fn run() -> Result<()> {
panic::init();
let args = clap::parse();
run_with_args(&args)
}

34
src/main/panic.rs Normal file
View file

@ -0,0 +1,34 @@
use std::{backtrace::Backtrace, panic};
/// Initialize the panic hook to capture backtraces at the point of panic.
/// This is needed to capture the backtrace before the unwind destroys it.
pub(crate) fn init() {
let default_hook = panic::take_hook();
panic::set_hook(Box::new(move |info| {
let backtrace = Backtrace::force_capture();
let location_str = info.location().map_or_else(String::new, |loc| {
format!(" at {}:{}:{}", loc.file(), loc.line(), loc.column())
});
let message = if let Some(s) = info.payload().downcast_ref::<&str>() {
(*s).to_owned()
} else if let Some(s) = info.payload().downcast_ref::<String>() {
s.clone()
} else {
"Box<dyn Any>".to_owned()
};
let thread_name = std::thread::current()
.name()
.map_or_else(|| "<unnamed>".to_owned(), ToOwned::to_owned);
eprintln!(
"\nthread '{thread_name}' panicked{location_str}: \
{message}\n\nBacktrace:\n{backtrace}"
);
default_hook(info);
}));
}