thiserror
自定义错误类型
thiserror 是 CoddyKit 上的免费 Learn Rust Coding 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Learn Rust Coding 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Learn Rust Coding 课程共包含 4 节课。
为什么需要自定义错误?
库应公开有意义的错误类型,以便调用方针对具体失败情况作出响应。手动编写这些类型意味着需要编写大量样板代码。thiserror 软件包可以为您生成这些代码。
添加 thiserror
将其添加为依赖项。它是一个派生宏软件包,不会产生运行时开销。
[dependencies]
thiserror = "1.0"定义错误枚举
在枚举上派生 Error,并让每个变体表示一种不同的失败情况。#[error("...")] 注解提供 Display 消息。
use thiserror::Error;
#[derive(Error, Debug)]
pub enum DataError {
#[error("item not found")]
NotFound,
#[error("invalid input: {0}")]
Invalid(String),
}插入字段值
消息字符串可以引用命名字段或位置字段,因此错误文本能够携带上下文信息。
use thiserror::Error;
#[derive(Error, Debug)]
pub enum ConfigError {
#[error("missing key: {key}")]
Missing { key: String },
#[error("value {0} out of range")]
OutOfRange(i32),
}自动实现 Display 和 Error
派生宏会自动实现 Display(使用您提供的消息)和 std::error::Error。无需手动编写 impl 块。
封装源错误
#[from] 会生成一个 From impl,使 ? 运算符能够将底层错误转换为您的类型。#[source] 用于标记原因。
use thiserror::Error;
#[derive(Error, Debug)]
pub enum AppError {
#[error("io failure")]
Io(#[from] std::io::Error),
#[error("parse failure")]
Parse(#[from] std::num::ParseIntError),
}与 ? 一起使用
借助 #[from],? 运算符可以自动将标准错误转换为您的 AppError。
fn read_number(path: &str) -> Result<i32, AppError> {
let text = std::fs::read_to_string(path)?; // io::Error -> AppError
let n: i32 = text.trim().parse()?; // ParseIntError -> AppError
Ok(n)
}源错误链
封装错误时,thiserror 会通过 Error::source 暴露其原因,从而支持完整的错误链,便于记录日志和调试。
透明错误
#[error(transparent)] 会将 Display 和源错误都转发给被封装的错误,适用于直通型变体。
use thiserror::Error;
#[derive(Error, Debug)]
pub enum WrapError {
#[error(transparent)]
Other(#[from] std::io::Error),
}何时使用 thiserror
在以下情况下可以选择使用 thiserror:
- 您正在编写一个库
- 调用方需要匹配具体的错误变体
- 您希望拥有稳定且带类型的错误 API
对于只想让错误向上传递的应用程序,anyhow 通常更简单。
匹配变体
由于该错误是真正的枚举,调用方可以对它使用 match,针对每种失败类型作出不同响应。
fn handle(err: AppError) {
match err {
AppError::Io(_) => println!("retry the file operation"),
AppError::Parse(_) => println!("ask the user to fix input"),
}
}快速检查
#[from] 注解会在 thiserror 枚举中生成什么?
回顾
您已经学习了 thiserror 软件包:
#[derive(Error)]会生成 Display 和 Error 的 impl#[error("...")]使用字段插值定义消息#[from]支持从源错误进行?转换transparent会将内容转发给被封装的错误- 非常适合构建带类型的库错误 API
常见问题解答
「thiserror」课时是免费的吗?
是的 — 「thiserror」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Learn Rust Coding 课程的其余内容,请升级到 CoddyKit PRO。 Learn Rust Coding 课程共包含 4 节课。
「thiserror」这节课中我会学到什么?
自定义错误类型 你通过在浏览器中直接运行的动手代码来练习 Learn Rust Coding,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Learn Rust Coding 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Learn Rust Coding 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「thiserror」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Learn Rust Coding 课中编写并运行代码吗?
能。每节 Learn Rust Coding 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- Result 与 ? 运算符
- thiserror
- anyhow
- 错误转换