Result { Err("err2"-6ren">
gpt4 book ai didi

rust - std::result::Result panic 记录

转载 作者:行者123 更新时间:2023-11-29 08:12:32 25 4
gpt4 key购买 nike

我在单独的线程中运行一些代码:

    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());
}));

我担心:

This will commonly, but not always, be a &'static str or String

但是 downcast 不会总是成功吗?

最佳答案

This will commonly, but not always, be a &'static str or 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,如果不是,则提供默认值,
  • 最后,我们打印所有累积的信息。

关于rust - std::result::Result panic 记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42456497/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com