直接回答:共识是库用 thiserror,应用用 anyhow。库需要给调用方一个精确、可匹配的错误枚举:thiserror 用宏从枚举生成 std::error::Error、Display、From 实现,调用方可以 match 具体变体决定对策。应用更关心错误沿调用链向上冒泡、最终在边界记录,anyhow 的 anyhow::Error 能装任何错误、自动携带上下文和 backtrace,? 直接透传,省去定义错误类型的样板。
展开解析:看典型写法对比。thiserror 库侧:#[derive(Error)] enum DbError { #[error("not found: {0}")] NotFound(u64), #[error(transparent)] Io(#[from] io::Error) },#[from] 自动生成转换让 ? 无缝工作。anyhow 应用侧:fn run() -> anyhow::Result<()>,用 .context("读取配置失败") 给底层错误包上业务语境,形成错误链。边界与坑:库暴露了 anyhow 类型会污染下游 API;anyhow 的错误不能 match 变体,要 downcast_ref 才能取回具体类型;thiserror 在错误变体爆炸时编译变慢,大库可拆分错误模块。还有 ? 的本质是 From 转换加提前返回,理解它就理解了为什么两种库都围绕 From 做文章。
追问方向:Box<dyn Error> 与 anyhow 的取舍?错误链的 source() 如何工作?panic 与 Result 的分工原则是什么?
(约 460 字)