63个稳定版本

1.0.63 2024年7月17日
1.0.61 2024年5月17日
1.0.58 2024年3月12日
1.0.53 2023年12月30日
1.0.6 2019年11月19日

1335过程宏

Download history 2611467/week @ 2024-05-04 2699611/week @ 2024-05-11 2775273/week @ 2024-05-18 2514655/week @ 2024-05-25 2645499/week @ 2024-06-01 2636042/week @ 2024-06-08 2590493/week @ 2024-06-15 2581584/week @ 2024-06-22 2330731/week @ 2024-06-29 2602455/week @ 2024-07-06 2772931/week @ 2024-07-13 2870385/week @ 2024-07-20 2847634/week @ 2024-07-27 2843911/week @ 2024-08-03 3040891/week @ 2024-08-10 2545634/week @ 2024-08-17

11,738,995 每月下载量
43,624 包中使用 (7 个直接使用)

MIT/Apache

60KB
1.5K SLoC

derive(Error)

github crates.io docs.rs build status

此库提供了一个方便的 derive 宏,用于标准库中的 std::error::Error 特征。

[dependencies]
thiserror = "1.0"

编译器支持:需要 rustc 1.56+


示例

use thiserror::Error;

#[derive(Error, Debug)]
pub enum DataStoreError {
    #[error("data store disconnected")]
    Disconnect(#[from] io::Error),
    #[error("the data for key `{0}` is not available")]
    Redaction(String),
    #[error("invalid header (expected {expected:?}, found {found:?})")]
    InvalidHeader {
        expected: String,
        found: String,
    },
    #[error("unknown data store error")]
    Unknown,
}

详情

  • Thiserror 故意不出现在你的公共API中。你将得到与手动编写 std::error::Error 实现相同的结果,从手动实现切换到 thiserror 或反之亦然不是破坏性变更。

  • 错误可以是枚举、具有命名字段的元组结构体、单元结构体或元组结构体。

  • 如果你在你的结构体或枚举的每个变体上提供 #[error)"..."] 消息,将为你的错误生成一个 Display 实现,如示例中所示。

    消息支持从错误中插值的简写。

    • #[error("{var}")] ⟶ write!("{}", self.var)
    • #[error("{0}")] ⟶ write!("{}", self.0)
    • #[error("{var:?}")] ⟶ write!("{:?}", self.var)
    • #[error("{0:?}")] ⟶ write!("{:?}", self.0)

    这些缩写可以与任何额外的格式参数一起使用,这些参数可以是任意表达式。例如

    #[derive(Error, Debug)]
    pub enum Error {
        #[error("invalid rdo_lookahead_frames {0} (expected < {})", i32::MAX)]
        InvalidLookahead(u32),
    }
    

    如果其中一个额外的表达式参数需要引用结构体或枚举的字段,那么请按.var引用命名字段,并按.0引用元组字段。

    #[derive(Error, Debug)]
    pub enum Error {
        #[error("first letter must be lowercase but was {:?}", first_char(.0))]
        WrongCase(String),
        #[error("invalid index {idx}, expected at least {} and at most {}", .limits.lo, .limits.hi)]
        OutOfBounds { idx: usize, limits: Limits },
    }
    
  • 为包含具有#[from]属性的每个变体生成一个From实现。

    使用#[from]的变体不得包含除源错误(以及可能的回溯——见下文)之外的任何其他字段。通常,#[from]字段是无名的,但在命名字段上也可以使用#[from]

    #[derive(Error, Debug)]
    pub enum MyError {
        Io(#[from] io::Error),
        Glob(#[from] globset::Error),
    }
    
  • 实现了Error特质的source()方法,以返回具有#[source]属性或命名为source的字段,如果有任何。这是为了识别导致您错误的底层错误。

    属性 #[from] 总是意味着相同的字段是 #[source],因此您无需同时指定这两个属性。

    任何实现了 std::error::Error 或指向 dyn std::error::Error 的错误类型都可以用作源。

    #[derive(Error, Debug)]
    pub struct MyError {
        msg: String,
        #[source]  // optional if field name is `source`
        source: anyhow::Error,
    }
    
  • Error 特性的 provide() 方法被实现,以提供具有名为 Backtrace 的类型的任何字段,如果有,作为 std::backtrace::Backtrace。在错误中使用 Backtrace 需要使用 Rust 版本 1.73 或更新的夜间编译器。

    use std::backtrace::Backtrace;
    
    #[derive(Error, Debug)]
    pub struct MyError {
        msg: String,
        backtrace: Backtrace,  // automatically detected
    }
    
  • 如果一个字段既是源(命名为 source,或者具有 #[source]#[from] 属性)并且标记了 #[backtrace],那么 Error 特性的 provide() 方法将被转发到源的 provide,以便错误的两层都共享相同的回溯。该 #[backtrace] 属性需要使用 Rust 版本 1.73 或更新的夜间编译器。

    #[derive(Error, Debug)]
    pub enum MyError {
        Io {
            #[backtrace]
            source: io::Error,
        },
    }
    
  • 对于使用 #[from] 并包含 Backtrace 字段的变体,回溯将在 From 实现内部捕获。

    #[derive(Error, Debug)]
    pub enum MyError {
        Io {
            #[from]
            source: io::Error,
            backtrace: Backtrace,
        },
    }
    
  • 错误可以使用 error(transparent) 将源和 Display 方法直接转发到底层错误,而不添加额外的消息。这对于需要“其他一切”变体的枚举来说很合适。

    #[derive(Error, Debug)]
    pub enum MyError {
        ...
    
        #[error(transparent)]
        Other(#[from] anyhow::Error),  // source and Display delegate to anyhow::Error
    }
    

    另一个用例是在不破坏软件包的公共 API 的情况下,隐藏错误表示的实现细节,从而使表示能够进化。

    // PublicError is public, but opaque and easy to keep compatible.
    #[derive(Error, Debug)]
    #[error(transparent)]
    pub struct PublicError(#[from] ErrorRepr);
    
    impl PublicError {
        // Accessors for anything we do want to expose publicly.
    }
    
    // Private and free to change across minor version of the crate.
    #[derive(Error, Debug)]
    enum ErrorRepr {
        ...
    }
    
  • 有关在应用程序代码中使用方便的单个错误类型,请参阅 anyhow 库。


与 anyhow 的比较

如果关心设计自己的专用错误类型,以便在失败时调用者收到您选择的确切信息,请使用 thiserror。这通常适用于类似库的代码。如果您不关心函数返回什么错误类型,只想让它变得简单,请使用 Anyhow。这在类似应用程序的代码中很常见。


许可证

根据您的选择,许可协议为 Apache License, Version 2.0MIT license
除非您明确说明,否则您根据Apache-2.0许可证定义,故意提交以包含在此crate中的任何贡献,均应按上述方式双许可,不得附加任何额外条款或条件。

依赖项

~265–720KB
~17K SLoC