Skip to main content

obeli_sk_utils/
panic_hook.rs

1pub fn tracing_panic_hook(panic_info: &std::panic::PanicHookInfo) {
2    let payload = panic_info.payload();
3    #[expect(clippy::manual_map)]
4    let payload = if let Some(s) = payload.downcast_ref::<&str>() {
5        Some(&**s)
6    } else if let Some(s) = payload.downcast_ref::<String>() {
7        Some(s.as_str())
8    } else {
9        None
10    }
11    .unwrap_or_default();
12    let location = panic_info.location().map(ToString::to_string);
13    let backtrace = std::backtrace::Backtrace::capture();
14    if backtrace.status() == std::backtrace::BacktraceStatus::Captured {
15        if tracing::enabled!(tracing::Level::ERROR) {
16            tracing::error!(
17                panic.location = location,
18                "A panic occurred: `{payload}` {backtrace}"
19            );
20        } else {
21            eprintln!("A panic occurred: `{payload}`\n{backtrace}");
22        }
23    } else if tracing::enabled!(tracing::Level::ERROR) {
24        tracing::error!(panic.location = location, "A panic occurred: `{payload}`",);
25    } else {
26        eprintln!("A panic occurred: `{payload}`");
27        eprintln!("A panic occurred");
28    }
29}