#error #error-reporting #error-context #error-message #cli-applications #status #utilities

bin+lib 叙述

叙述是一套用于错误处理和状态报告的 CLI 应用程序工具

9 个版本

0.4.2 2024 年 7 月 12 日
0.4.1 2023 年 6 月 8 日
0.4.0 2022 年 11 月 24 日
0.3.0 2022 年 10 月 19 日
0.1.3 2022 年 9 月 28 日

#109命令行界面

每月 39 次下载

MIT/Apache

60KB
717

叙述

Crates.io msrv 1.70.0 tests Documentation license

此库提供了 CLI 应用程序错误和状态报告工具。彩色输出格式旨在与 Cargo 类似。错误类型是 anyhow 的包装,带有可选的帮助信息。

特性

  • 面向用户的状况消息和错误报告
  • 用附加上下文包装任何错误
  • 错误的可选帮助信息
  • 一组符合 sysexits.h 的标准 CLI 错误和退出代码
  • 便利的 Result 类型
  • 替换/集成 anyhow

如何使用

  • 使用 narrate::Result<T> 作为任何可能失败的函数的返回类型。

    在函数内部,使用 ? 来传播实现了 std::error::Error 特性的任何错误。与 anyhow::Result<T> 相同。

    use narrate::Result;
    
    fn get_user() -> Result<User> {
        let json = std::fs::read_to_string("user.json")?;
        let user: User = serde_json::from_str(&json)?;
        Ok(user)
    }
    
  • 通过导入 narrate::ErrorWrap 特性来包装错误,并添加更多上下文。类似于 anyhow::Context,这可以为用户提供更多关于错误发生原因的信息。

    use narrate::{CliError, ErrorWrap, Result};
    
    fn run() -> Result<()> {
        ...
        // wrap with contextual information
        data.acquire().wrap("unable to acquire data")?;
    
        // wrap with another error
        config.load().wrap(CliError::Config)?;
    
        // wrap with lazily evaulated string or error
        config.load().wrap_with(|| format!("cannot load {}", path))?;
    
        // wrap with help information
        create_dir()
          .wrap("project directory already exists")
          .add_help("Try using cargo init")?;
        ...
    }
    
    error: project directory already exists
    cause: Is a directory (os error 20)
    
    Try using cargo init
    
  • 使用 narrate::ExitCode 特性从 narrate::Error 获取符合 sysexits.h 的退出代码。默认情况下,这仅是 70 (软件错误),但使用适当的 CliError 将会改变这一点。

  • narrate::CliError 是一组典型的命令行错误。使用它们为更深层应用程序的错误添加上下文。使用它们的 exit_code 来符合 sysexits.h。

    use narrate::{CliError, ErrorWrap, ExitCode, Result};
    
    fn main() {
        let res = run();
    
        if let Err(ref err) = res {
            std::process::exit(err.exit_code());
        }
    }
    
    fn run() -> Result<()> {
        will_error().wrap(CliError::OsErr)?
        Ok(())
    }
    
  • 使用 report::errreport::err_full 报告完整错误链到命令行。

    use narrate::{CliError, Error, report};
    
    fn main() {
        let res = run();
    
        if let Err(ref err) = res {
            report::err_full(&err);
            std::process::exit(err.exit_code());
        }
    }
    
    fn run() -> Result<()> {
        ...
        let config: Config = serde_json::from_str(&json)
            .wrap("bad config file `/app/config.toml`")
            .wrap(CliError::Config)
            .add_help("see https://docs.example.rs/config for more help")?;
        ...
    }
    

    report::err_full output

  • 使用 report::status 将应用程序状态报告到命令行。模仿 Cargo 的输出。

    use narrate::{Color, report};
    
    fn main() {
        report::status("Created", "new project `spacetime`", Color::Green);
    }
    

    report::status output

请查看 API 文档示例 了解更多信息。

常见问题解答

我应该使用 narrate 而不是 anyhoweyre 吗?

Anyhow 是处理 CLI 应用程序中错误的一个很好的工具,但它没有自己的报告、常用错误集或添加单独帮助消息的能力。

Eyre 及其相关软件包提供了细粒度的错误报告,并且比 narrate 更具可定制性 - narrate 在模仿 Cargo 风格方面有偏见。如果您不需要那么多控制,narrate 提供了一个更简单的替代方案。此外,narrate 还提供了报告状态的功能,而不仅仅是错误。

我可以只美化打印我的 anyhow 错误吗?

如果您仅使用 report Cargo 功能标志,则可以访问 report 模块,从而访问 anyhow_erranyhow_err_full 函数。

# Cargo.toml
[dependencies]
narrate = { version = "0.4.2", default-features = false, features = ["report"] }
// main.rs
use narrate::report;

fn main() {
    if let Err(err) => run() {
        report::anyhow_err_full(err);    
    }
}

fn run() -> anyhow::Result<()> {
  ...
}

贡献

非常感谢您考虑为此项目做出贡献!

我们欢迎任何形式的贡献

  • 新问题(功能请求、错误报告、问题、想法、...)
  • 拉取请求(文档改进、代码改进、新功能、...)

注意:在您花费时间打开拉取请求之前,请先打开一个问题。

有关详细信息,请参阅 CONTRIBUTING.md

许可证

narrate 在 MIT 许可证和 Apache 许可证(版本 2.0)的条款下分发。

请参阅LICENSE-APACHELICENSE-MIT获取详细信息。

依赖项

~0–9.5MB
~41K SLoC