--release 的恐慌!()和期望()的替代品?

fad*_*bee 8 panic rust

在开发中,我的代码使用.expect()panic!()来处理致命错误。

他们的行为正是我在开发过程中所需要的。

当我使用 进行编译时--release,我希望它们的输出会变得更加简洁。

即这段代码:

let mut file_a = OpenOptions::new().write(true)
                                   .read(true)
                                   .open(args.file_a).expect("foo bar");
Run Code Online (Sandbox Code Playgroud)

生成:

thread 'main' panicked at 'foo bar: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/bin/vsapply.rs:131:59
Run Code Online (Sandbox Code Playgroud)

当我只想:

foo bar: No such file or directory
Run Code Online (Sandbox Code Playgroud)

当用--release.

已经有办法做到这一点了吗?

ebe*_*ard 7

您可以使用的一种选择是,不要惊慌失措,而是通过使用eprintln!()非零错误代码并退出来将信息打印到 stderr。

use std::process;

fn main() -> {
    // some terrible state
    eprintln!("foo bar: No such file or directory.");
    process::exit(1);
}
Run Code Online (Sandbox Code Playgroud)

这样做有几个好处:

  • 打印到 stderr 可确保您的错误消息不会定向到某个输出文件(例如foo --option arg1 arg2 > output.txt)。
  • 调用您的程序的程序可以将非零错误代码解释为失败的指示。


Aki*_*AKI 4

std::panic::set_hook#[cfg(debug_assertions)]的组合解决了这个问题。

use std::panic;

fn main() {
    #[cfg(not(debug_assertions))]
    panic::set_hook(Box::new(|panic_info| {
        if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
            println!("panic occurred: {:?}", s);
        } else {
            println!("panic occurred");
        }
    }));
    println!("Hello, world!");
    panic!("nyaan");
}
Run Code Online (Sandbox Code Playgroud)

当 exec 时cargo run,输出为:

Hello, world!
thread 'main' panicked at 'nyaan', src\main.rs:14:5
Run Code Online (Sandbox Code Playgroud)

什么时候cargo run --release

Hello, world!
panic occurred: "nyaan"
Run Code Online (Sandbox Code Playgroud)