How to prevent: thread panicked while processing panic. aborting

One of my users has reported having this error message:
thread panicked while processing panic. aborting.
Even with the same data on the same OS I can't reproduce the bug.

Here's my main():

fn main() {
    panic::set_hook(Box::new(|info| {
        eprint!(
            "Unexpected error: {}",
            info.payload().downcast_ref::<&str>().unwrap()
        );
        if let Some(location) = info.location() {
            eprint!(" ({} {})", location.file(), location.line());
        }
        eprintln!("");
    }));
    let code = real_main(); // returns an i32
    process::exit(code);
}

I thought this would catch all panics and at least cleanly exit, but it seems not. Is it possible to make it catch any panic and at least cleanly exit. Ideally saying why/where it panicked?

This unwrap may be panicing. According to the docs, payload "will commonly, but not always, be a &'static str or String ." If it's a String, then your downcast_ref will return None.

Thanks! I don't know how I missed that.

To be more precise, if panicked via panic!("Static message") the payload will be a &'static str. If there were format arguments (panic!("{}", something)), the payload will be a String. But it can also be something else.

Example (playground):

fn main() {
    panic::set_hook(Box::new(|info| {
        let (msg, msg_type): (&str, &str) = if let Some(&msg) = info.payload().downcast_ref::<&str>() {
            (msg, "(&str): ")
        } else if let Some(msg) = info.payload().downcast_ref::<String>() {
            (msg, "(String): ")
        } else {
            ("", "(unknown message type)")
        };
        eprint!("Unexpected error {}{}", msg_type, msg);
        if let Some(location) = info.location() {
            eprint!(" ({} {})", location.file(), location.line());
        }
        eprintln!("");
    }));
    
    panic::catch_unwind(|| panic!("Static message")).unwrap_err();
    panic::catch_unwind(|| panic!("Dynamic: {}", 123)).unwrap_err();
    panic::catch_unwind(|| panic!(123)).unwrap_err();
}