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
每月下载量 11,746,204
用于 43,591 个crate (17,135 直接)
31KB
325 行
derive(Error)
此库提供了一种方便的 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