2 个稳定版本

2.0.2 2022 年 5 月 27 日

#83Rust 模式

Download history 10657/week @ 2024-03-14 11438/week @ 2024-03-21 11565/week @ 2024-03-28 17151/week @ 2024-04-04 13015/week @ 2024-04-11 11062/week @ 2024-04-18 12224/week @ 2024-04-25 16652/week @ 2024-05-02 11351/week @ 2024-05-09 11572/week @ 2024-05-16 11502/week @ 2024-05-23 11953/week @ 2024-05-30 10480/week @ 2024-06-06 13506/week @ 2024-06-13 16315/week @ 2024-06-20 11097/week @ 2024-06-27

53,218 每月下载量
63 个crate(直接使用 34 个) 中使用

MIT/Apache

25KB
227

derive(Error)

github crates.io docs.rs build status

该库提供了一个方便的 derive 宏,用于标准库的 std::error::Error trait。

[dependencies]
thiserror = "1.0"

编译器支持:需要 rustc 1.31+


示例

use thiserror_no_std::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 trait 相同,从手动实现 impl 切换到 thiserror 或反之亦然不会造成破坏性变更。

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

  • 如果你在 struct 或枚举的每个变体上提供了 #[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 实现内部捕获回溯。

    #[derive(Error, Debug)]
    pub enum MyError {
        Io {
            #[from]
            source: io::Error,
            backtrace: Backtrace,
        },
    }
    
  • 实现了 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 特质的 backtrace() 方法,以返回具有名为 Backtrace 的类型的任何字段,如果有的话。

    use std::backtrace::Backtrace;
    
    #[derive(Error, Debug)]
    pub struct MyError {
        msg: String,
        backtrace: Backtrace,  // automatically detected
    }
    
  • 如果一个字段既是源(命名为 source,或者有 #[source]#[from] 属性)并且 被标记为 #[backtrace],则错误特质的 backtrace() 方法将转发到源的回溯。

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

    #[derive(Error, Debug)]
    pub enum MyError {
        ...
    
        #[error(transparent)]
        Other(#[from] anyhow::Error),  // source and Display delegate to anyhow::Error
    }
    
  • 有关在应用程序代码中使用方便的单个错误类型的库,请参阅anyhow


与anyhow的比较

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


许可证

根据您的选择,许可协议为 Apache License, Version 2.0MIT license
除非您明确表示,否则,根据 Apache-2.0 许可证的定义,您有意提交以包含在此软件包中的任何贡献,都将按照上述方式双重许可,而不添加任何额外的条款或条件。

依赖项

~1.5MB
~35K SLoC