结论:两者分工不同——库代码用 thiserror 定义具体的错误枚举(精确实现 std::error::Error,调用方可 match 处理);应用/二进制代码用 anyhow 快速传播错误(anyhow::Result<T> 统一错误类型,并可附加上下文)。
展开:thiserror 通过 derive 宏生成 Error/Display/From 实现,保留错误结构,库的用户可以匹配具体变体决定重试还是放弃;anyhow 提供类型擦除的错误对象、? 自动转换和 .context() 上下文链,适合"出错就向上报"的应用层,代价是丢失结构化信息(只能靠 downcast 取回)。易错点:①库里用 anyhow 会强迫用户接受不透明错误,是 API 设计反模式;②公开错误枚举加 #[non_exhaustive] 保留演进空间;③? 依赖 From 转换,thiserror 的 #[from] 自动生成。追问方向:错误信息给用户看还是给程序判断?Display 面向用户,枚举变体结构面向程序分支。
#[derive(thiserror::Error, Debug)]
pub enum StoreError {
#[error("io failed")]
Io(#[from] std::io::Error),
#[error("key not found: {0}")]
NotFound(String),
}
// 应用层:fn run() -> anyhow::Result<()> { f().context("loading config")?; }