64 个稳定版本

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 日

Rust 模式 中排名 #3

Download history 2620421/week @ 2024-05-03 2694860/week @ 2024-05-10 2762025/week @ 2024-05-17 2540347/week @ 2024-05-24 2647968/week @ 2024-05-31 2632291/week @ 2024-06-07 2589832/week @ 2024-06-14 2634482/week @ 2024-06-21 2379767/week @ 2024-06-28 2480794/week @ 2024-07-05 2776361/week @ 2024-07-12 2867624/week @ 2024-07-19 2793954/week @ 2024-07-26 2854393/week @ 2024-08-02 3035543/week @ 2024-08-09 2548893/week @ 2024-08-16

每月下载量 11,746,204
用于 43,591 个crate (17,135 直接)

MIT/Apache

31KB
325

derive(Error)

github crates.io docs.rs build status

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

[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 实现相同的结果,从手动编写 impl 转换到 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),
    }
    
  • 错误特质的 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 trait)的 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],那么错误特质的 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.0 或 MIT 许可证下许可。
除非你明确说明,否则你提交给此软件包的任何有意贡献,根据 Apache-2.0 许可证的定义,都应按照上述方式双重许可,不附加任何额外条款或条件。

依赖项

约 300-760KB
约 18K SLoC