Exception 使用panic::catch\u unwind时抑制Rust中的紧急输出

Exception 使用panic::catch\u unwind时抑制Rust中的紧急输出,exception,rust,Exception,Rust,我经常感到恐慌: use std::panic; fn main() { let result = panic::catch_unwind(|| { panic!("test panic"); }); match result { Ok(res) => res, Err(_) => println!("caught panic!"), } } () 这似乎工作得很好,但我仍在将恐慌输出到stdout

我经常感到恐慌:

use std::panic;

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

    match result {
        Ok(res) => res,
        Err(_) => println!("caught panic!"),
    }
}
()

这似乎工作得很好,但我仍在将恐慌输出到stdout。我只想把这个打印出来:

陷入恐慌!
而不是

线程“”在“测试死机”时死机:6
注意:使用'RUST_BACKTRACE=1'运行回溯跟踪。
惊慌失措!
您需要注册一个不起任何作用的紧急挂钩。然后,您可以通过以下方式捕捉它:

正如,如果需要,您可以使用获取当前钩子以在以后恢复它

另见:


您可以使用
std::panic::set\u hook
来抑制输出。但是请注意,钩子是全局进程,它将禁止报告程序中可能发生的所有恐慌


正如我对一个类似问题的回答中所述,我已经编写了一个板条箱,它提供了一种使用可组合过滤器抑制钩子的方法,包括一个基于每个线程的过滤器。

使用以下
catch\u unwind\u silent
而不是常规
catch\u 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
}
使用std::panic;
fn catch_unwind_silent R+panic::UnwindSafe,R>(f:f)->std::thread::Result{
let prev_hook=panic::take_hook();
惊慌失措:设置钩子(框::新建(| |{}));
让结果=惊慌::抓住并放松(f);
惊慌失措:设钩(上钩);
结果
}

注意:可以先使用
take\u handler
在恢复后恢复原始处理程序。通常,您希望在main的开头安装一次紧急处理程序,然后再启动任何线程,并且永远不要卸载它。相反,紧急处理程序应该查看一个线程局部变量,以决定它是应该调用链中的下一个处理程序,还是应该默默地吞下紧急处理程序。
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
}