#错误 #错误处理 #回溯 #对象 #标准 #应用

已删除 lmnkjgkj-std-backtrace-anyhow

anyhow 的分支,使用 std 的回溯

1 个不稳定版本

0.0.1 2023年5月3日

#80#回溯

Download history 11/week @ 2024-03-13 14/week @ 2024-03-20 18/week @ 2024-03-27 22/week @ 2024-04-03 4/week @ 2024-04-17 40/week @ 2024-04-24 4/week @ 2024-05-01 22/week @ 2024-05-08

每月176 次下载

MIT/Apache

150KB
2.5K SLoC

带有 std 回溯的 anyhow

感谢 https://github.com/LukasKalbertodt


lib.rs:

githubcrates-iodocs-rs


此库提供了 [anyhow::Error][Error],这是一个基于 trait object 的错误类型,用于在 Rust 应用程序中轻松实现惯用的错误处理。


详细信息

  • 使用 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<()> {
        # return Ok(());
        #
        # const _: &str = stringify! {
        ...
        # };
        #
        # let it = It;
        # let path = "./path/to/instrs.json";
        #
        it.detach().context("Failed to detach the important thing")?;
    
        let content = std::fs::read(path)
            .with_context(|| format!("Failed to read instrs from {}", path))?;
        #
        # const _: &str = stringify! {
        ...
        # };
        #
        # Ok(())
    }
    
    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 或 features = ["backtrace"],则会在错误发生时捕获并打印回溯(如果底层错误类型本身没有提供)。要查看回溯,必须通过在 std::backtrace 中描述的环境变量启用。

    • 如果您希望恐慌和错误都拥有回溯,请设置 RUST_BACKTRACE=1;
    • 如果您只想错误有回溯,请设置 RUST_LIB_BACKTRACE=1;
    • 如果您只想恐慌有回溯,请设置 RUST_BACKTRACE=1RUST_LIB_BACKTRACE=0
  • Anyhow 适用于所有实现了 std::error::Error 接口错误类型,包括您在包中定义的错误类型。我们不捆绑 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);
    

无 std 支持

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

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

由于基于 ? 的错误转换通常依赖于仅在 std 中可用的 std::error::Error 接口,因此在处理返回 Anyhow 错误类型的函数中的非 Anyhow 错误类型时,需要显式使用 .map_err(Error::msg)

无运行时依赖