本页目录
Error trait 与生态
std::error::Error 只是 Display+Debug+source() 的组合——太薄了。thiserror 用 derive 宏给库生成结构化错误类型(调用方能 match),anyhow 给应用提供"不在意错误类型,只管向上传"的万能错误包装。库用 thiserror,应用用 anyhow——这不是教条,是实践中沉淀下来的分工。
std::error::Error trait
标准库的 Error trait 很简单——Display + Debug + source():
use Error;
use fmt;
source() 方法返回底层原因——形成错误链。anyhow 和 eyre 利用这个链自动生成 backtrace。
thiserror: library crate 的 derive macro
用于库——给 caller 提供可匹配的具体错误类型:
use Error;
#[from] 自动生成 From<io::Error> for DataStoreError,使 ? 可以自动转换。caller 可以用 match 区分错误类型。
anyhow: application code 的通用错误容器
用于应用/二进制——收集错误链,不关心具体类型:
use ;
anyhow::Error 可以存储任何 Error + Send + Sync + 'static。context() 给错误链添加人类可读的注释——这是 anyhow 最常用的模式。
何时用 thiserror vs anyhow
一条简单规则:库用 thiserror(给 caller choice),应用用 anyhow(收集错误上下文)。库不应该强制 caller 使用特定的错误报告库——抛具体的、可匹配的类型。应用不需要区分错误类型——需要的是所有错误都被捕获、记录,并有足够的上下文重现 bug。
参考
- thiserror: docs.rs/thiserror
- anyhow: docs.rs/anyhow
Keywords: Error trait, thiserror, anyhow, context, source, error chain, #[from]