本文为『Zino开发框架技术解读』系列的第二篇。

在Zino开发框架中,咱们定义了一个通用的谬误类型Error,次要目标是实现以下性能:

  1. 基于字符串将任意谬误包装成同一类型;
  2. 反对source,并能溯源到原始谬误;
  3. 反对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就会主动生成一条记录:

全副代码加起来就一百行左右:

清晰易懂,简洁优雅!