本文为『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 就会主动生成一条记录:
全副代码加起来就一百行左右:
清晰易懂,简洁优雅!