85 个稳定版本

1.0.86 2024 年 5 月 18 日
1.0.82 2024 年 4 月 10 日
1.0.81 2024 年 3 月 12 日
1.0.78 2023 年 12 月 30 日
0.0.0 2019 年 10 月 5 日

#10 in Rust 模式

Download history 2107322/week @ 2024-05-02 2112317/week @ 2024-05-09 2248274/week @ 2024-05-16 2148589/week @ 2024-05-23 2380259/week @ 2024-05-30 2256352/week @ 2024-06-06 2384042/week @ 2024-06-13 2278257/week @ 2024-06-20 2228768/week @ 2024-06-27 2112821/week @ 2024-07-04 2329854/week @ 2024-07-11 2328830/week @ 2024-07-18 2393551/week @ 2024-07-25 2410316/week @ 2024-08-01 2644130/week @ 2024-08-08 2373850/week @ 2024-08-15

10,267,814 每月下载量
用于 25,809 个crate (16,106 直接)

MIT/Apache

165KB
3K SLoC

Anyhow ¯\_(°ペ)_/¯

github crates.io docs.rs build status

此库提供了 anyhow::Error,一个基于 trait object 的错误类型,以便在 Rust 应用程序中轻松进行惯用错误处理。

[dependencies]
anyhow = "1.0"

编译器支持:需要 rustc 1.39+


详情

  • 使用 Result<T, anyhow::Error>,或者等价地 anyhow::Result<T>,作为任何有故障函数的返回类型。

    在函数内,使用 ? 来轻松传播实现了 std::error::Error trait 的任何错误。

    use anyhow::Result;
    
    fn get_cluster_info() -> Result<ClusterMap> {
        let config = std::fs::read_to_string("cluster.json")?;
        let map: ClusterMap = serde_json::from_str(&config)?;
        Ok(map)
    }
    
  • 附加上下文以帮助正在调试错误的人了解事情出错的地方。例如,在没有更多上下文的情况下,关于应用程序正在执行哪个高级步骤的低级错误(如“找不到文件或目录”)可能会很麻烦。

    use anyhow::{Context, Result};
    
    fn main() -> Result<()> {
        ...
        it.detach().context("Failed to detach the important thing")?;
    
        let content = std::fs::read(path)
            .with_context(|| format!("Failed to read instrs from {}", path))?;
        ...
    }
    
    Error: Failed to read instrs from ./path/to/instrs.json
    
    Caused by:
        No such file or directory (os error 2)
    
  • 支持向下转换,并且可以根据需要按值、按共享引用或按可变引用进行。

    // If the error was caused by redaction, then return a
    // tombstone instead of the content.
    match root_cause.downcast_ref::<DataStoreError>() {
        Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
        None => Err(error),
    }
    
  • 如果使用 Rust ≥ 1.65,则会捕获并打印回溯,前提是底层错误类型本身没有提供。要查看回溯,必须通过 std::backtrace 中描述的环境变量来启用。

    • 如果您希望恐慌和错误都具有回溯,请设置 RUST_BACKTRACE=1;
    • 如果您只想让错误具有回溯,请设置 RUST_LIB_BACKTRACE=1;
    • 如果只想让恐慌产生回溯,请设置 RUST_BACKTRACE=1RUST_LIB_BACKTRACE=0
  • Anyhow 与任何实现了 std::error::Error 的错误类型兼容,包括你在你的crate中定义的错误。我们没有捆绑 derive(Error) 宏,但你可以自己编写实现或使用独立的宏,如 thiserror

    use thiserror::Error;
    
    #[derive(Error, Debug)]
    pub enum FormatError {
        #[error("Invalid header (expected {expected:?}, got {found:?})")]
        InvalidHeader {
            expected: String,
            found: String,
        },
        #[error("Missing attribute: {0}")]
        MissingAttribute(String),
    }
    
  • 可以使用 anyhow! 宏构造一次性错误消息,该宏支持字符串插值并生成 anyhow::Error

    return Err(anyhow!("Missing attribute: {}", missing));
    

    提供了一个 bail! 宏作为早期返回的快捷方式。

    bail!("Missing attribute: {}", missing);
    

无标准支持

在 no_std 模式下,几乎所有的 API 都可用且工作方式相同。要在 no_std 模式下依赖 Anyhow,请在 Cargo.toml 中禁用我们默认启用的 "std" 功能。需要一个全局分配器。

[dependencies]
anyhow = { version = "1.0", default-features = false }

由于基于 ? 的错误转换通常会依赖于仅在 std 中可用的 std::error::Error 特性,no_std 模式将需要在函数中处理非 Anyhow 错误类型时显式使用 .map_err(Error::msg)


与 failure 的比较

anyhow::Error 类型与 failure::Error 类似,但与 failure 不同,我们的实现是基于标准库的 std::error::Error 特性,而不是单独的特性 failure::Fail。标准库已经采纳了必要的改进,以便能够作为 RFC 2504 的一部分实现。


与 thiserror 的比较

如果你不关心函数返回的错误类型,只想让它容易实现,请使用 Anyhow。这在应用程序代码中很常见。如果你是想要设计自己的专用错误类型(以便在失败时调用者获得你选择的确切信息)的库,请使用 thiserror


许可证

根据您的选择,在 Apache License, Version 2.0MIT license 下许可。
除非您明确声明,否则您有意提交给此crate的任何贡献,根据 Apache-2.0 许可证的定义,应按上述方式双重许可,不附加任何额外条款或条件。

依赖项

~0–530KB
~11K SLoC