我在一个单独的线程中运行一些代码:
fn f1() -> Result<(), String> { Err("err1".to_string()) }
fn f2() -> Result<(), String> { Err("err2".to_string()) }
::std::thread::spawn(move || {
f1().expect("f1 failed");
f2().expect("f2 failed");
});
我也使用log crate进行记录。
结果,我希望panic!
拨打error!
而不是print!
。
我找到了panic hook,但在这样的代码中我不喜欢unwrap
:
panic::set_hook(Box::new(|panic_info| {
error!("panic occured: {:?}", panic_info.payload().downcast_ref::<&str>().unwrap());
}));
我很担心:
这通常是
,但并非总是如此&'static str
或String
但downcast
总是不会成功?
答案 0 :(得分:4)
这通常是
,但并非总是如此&'static str
或String
这意味着开发人员(您使用的库中的一个)可能会使用其他类型。在这种情况下,对downcast_ref
的调用将失败。
我的建议是处理您所了解的案例,并添加一个包含默认消息的全包案例。
此外,您还应该考虑打印位置,因为即使没有消息,它也非常有用。
全部告诉:
use std::panic;
use std::ops::Deref;
panic::set_hook(Box::new(|panic_info| {
let (filename, line) =
panic_info.location().map(|loc| (loc.file(), loc.line()))
.unwrap_or(("<unknown>", 0));
let cause = panic_info.payload().downcast_ref::<String>().map(String::deref);
let cause = cause.unwrap_or_else(||
panic_info.payload().downcast_ref::<&str>().map(|s| *s)
.unwrap_or("<cause unknown>")
);
error!("A panic occurred at {}:{}: {}", filename, line, cause);
}));
让我们打开它:
payload
是否为String
,如果是,则取消引用&str
,如果没有提供默认值,