Formatting "any" field from panic_hook

I have a simple panic catcher:

// Set a custom panic hook
std::panic::set_hook(Box::new(|info| {
    log::error!("PANIC: {:?}", info);
}));

The panic it's catching is in the mysql crate::

match Self::from_row_opt(row) {
            Ok(x) => x,
            Err(FromRowError(row)) => panic!(
                "Couldn't convert {:?} to type {}. (see FromRow documentation)",
                row,
                type_name::<Self>(),
            ),
        }

Catching it works fine, but the error I get is

20:04:28 [ERROR] PANIC: PanicHookInfo { payload: Any { .. }, location: Location { file: "/home/john/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/mysql_common-0.36.2/src/row/convert/mod.rs", line: 84, column: 39 }, can_unwind: true, force_no_backtrace: false }

The "payload" field, which is an Any, doesn't get displayed by {:?}, probably because it's boxed. What's the recommended way to decode that?

(This is running inside an FCGI server, so I don't get stderr. Just what I log.)

Every panic payload is either a String or a &'static str, unless someone calls panic_any(), which the standard library will not do itself. panic_any() is, in practice, only used for special circumstances like using unwinding for structured error handling.

So, try downcasting to each of String and &'static str, and that will be sufficient.

3 Likes

Exactly, AI pointed to that too:

panic::set_hook(Box::new(|panic_info| {
        if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
            eprintln!("Abnormal RustBee termination: {s:?}")
        } else if let Some(s) = panic_info.payload().downcast_ref::<String>() {
            eprintln!("Abnormal RustBee termination: {s:?}")
        } else {
            eprintln!("Abnormal RustBee termination")
        }
     }));