本文为『Zino开发框架技术解读』系列的第二篇。
在Zino开发框架中,我们定义了一个通用的错误类型Error,主要目的是实现以下功能:
- 基于字符串将任意错误包装成同一类型;
- 支持source,并能溯源到原始错误;
- 支持tracing,自动记录错误信息。
这三条需求对于Zino框架至关重要,这也是为什么我们没有采用社区中的错误处理库,比如anyhow。在实际应用开发中,我们往往并不会对具体的错误类型做不同的处理,而是直接返回错误消息,所以我们采取基于字符串的错误处理: 其中SharedString是Zino中用来优化静态字符串处理的类型。很多人认为Rust标准库中的String类型就应该定义成Cow<'static, str> (当然,这又是一个性能和使用便利性的取舍问题)。所以,我们的Error类型对于静态字符串的处理有巨大的性能优势,后期的bench也验证了这一点: zino::error::Error在处理 &'static str消息时只需要2.5ns;相比之下,anyhow::Error需要60ns。
Error类型的方法实现就很直接了当:其中 .sources() 返回的是一个迭代器,在anyhow中称为Chain(我们这里的命名与核心库中的core::error::Source保持一致)。
至此,我们实现了错误溯源的功能,并提供了 .root_source() 方法来追溯到原始错误。接着,我们需要将任一错误类型E: std::error::Error + 'static转换为Error类型(其中 'static的生命周期限制是必须的,这是std::error::Error::source() 方法的要求):这样,我们就可以在需要返回Result<T, zino::error::Error> 的函数中方便地使用 ? 运算符(注意,我们的Error类型本身并没有实现std::error::Error)。
剩下的最后一个核心功能就是如何与tracing集成,让它自动记录错误信息:这里的关键就是实现std::fmt::Display。每当我们调用 .to_string() 时,tracing::error就会自动生成一条记录:
全部代码加起来就一百行左右:
清晰易懂,简洁优雅!
Ext Link: https://mp.weixin.qq.com/s?__biz=Mzg3MjY4NjE2Mw==&mid=2247483677&idx=1&sn=f58df05cc9ece8a42ce8095385575266&chksm=ceea3621f99dbf3733c97bb0cef0193c794dbb4b113cf26bf5a2ec6c4e1caa7dbf443e2f0f73&token=1756919940&lang=zh_CN#rd
评论区
写评论还没有评论