使用panic :: catch_unwind时,在Rust中抑制panic输出

Mat*_*att 12 exception rust

我正在panic::catch_unwind惊慌失措:

use std::panic;

fn main() {
    let result = panic::catch_unwind(|| {
        panic!("test panic");
    });

    match result {
        Ok(res) => res,
        Err(_) => println!("caught panic!"),
    }
}
Run Code Online (Sandbox Code Playgroud)

(游乐场)

这似乎工作得很好,但我仍然得到了恐慌的输出到stdout.我想这只打印出来:

caught panic!
Run Code Online (Sandbox Code Playgroud)

代替

thread '<main>' panicked at 'test panic', <anon>:6
note: Run with `RUST_BACKTRACE=1` for a backtrace.
caught panic!
Run Code Online (Sandbox Code Playgroud)

She*_*ter 15

您需要注册一个恐慌钩std::panic::set_hook不做任何事.然后你可以抓住它std::panic::catch_unwind:

use std::panic;

fn main() {
    panic::set_hook(Box::new(|_info| {
        // do nothing
    }));

    let result = panic::catch_unwind(|| {
        panic!("test panic");
    });

    match result {
        Ok(res) => res,
        Err(_) => println!("caught panic!"),
    }
}
Run Code Online (Sandbox Code Playgroud)

正如Matthieu M.所说std::panic::take_hook,如果你需要,你可以获得当前的钩子,以便之后恢复它.

也可以看看:

  • 注意:首先可以使用`take_handler`恢复后恢复原始处理程序. (2认同)
  • 在启动任何线程之前,您通常希望在 main 的开头安装一次紧急处理程序,并且永远不要卸载它。相反,恐慌处理程序应该查看线程局部变量来决定它是否应该调用链中的下一个处理程序,或者是否应该默默地吞下恐慌。 (2认同)

k06*_*06a 8

使用以下命令catch_unwind_silent而不是常规命令catch_unwind来实现预期异常的静默:

use std::panic;

fn catch_unwind_silent<F: FnOnce() -> R + panic::UnwindSafe, R>(f: F) -> std::thread::Result<R> {
    let prev_hook = panic::take_hook();
    panic::set_hook(Box::new(|_| {}));
    let result = panic::catch_unwind(f);
    panic::set_hook(prev_hook);
    result
}
Run Code Online (Sandbox Code Playgroud)