使用panic :: catch_unwind

时间:2016-02-22 16:51:50

标签: 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!"),
    }
}

Playground

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

caught panic!

而不是

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

3 个答案:

答案 0 :(得分:12)

你需要注册一个恐慌钩子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!"),
    }
}

作为Matthieu M. notes,您可以使用std::panic::take_hook获取当前挂钩,以便在需要时恢复它。

另见:

答案 1 :(得分:1)

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

在我对类似问题的回答中已经plugged,我已经写了一个箱子,提供了一种用可组合过滤器来抑制钩子的方法,包括一个可以在每个线程上工作的过滤器。 / p>

答案 2 :(得分:1)

使用以下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
}