0
点赞
收藏
分享

微信扫一扫

Rust中的错误处理

秦瑟读书 2022-09-01 阅读 71

AnyHow & ThisError

两个库都是用来处理错误的好帮手,AnyHow简单方便,ThisError帮助我们创建完备的错误类型。

AnyHow

使用方法

  • 在使用上来说,把任何可能会失败的函数(fallible function),把返回值的类型设置成Result<T, anyhow::Error>,或者等价的anyhow::Result<T>

    在函数内,就可以用?将任何implement了std::error::Error的错误传递出来。

    use anyhow::Result;

    fn get_cluster_info() -> Result<ClusterMap> {
    let config = std::fs::read_to_string("cluster.json")?;
    let map: ClusterMap = serde_json::from_str(
    Ok(map)
    }
  • 附加context来帮助触发了error的人来理解哪里不对了。尤其是一些low level的错误比如"No such file or directory"更需要增加一些信息。

    use anyhow::{Context, Result};

    fn main() -> Result<()> {
    ...
    it.detach().context("Failed to detach the important thing")?;

    let content = std::fs::read(path)
    .with_context(|| format!("Failed to read instrs from {}", path))?;
    ...
    }
    Error: Failed to read instrs from ./path/to/instrs.json

    Caused by:
    No such file or directory (os error 2)
  • Downcasting支持by value, by shared reference, by mutable reference.

    // If the error was caused by redaction, then return a
    // tombstone instead of the content.
    match root_cause.downcast_ref::<DataStoreError>() {
    Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
    None => Err(error),
    }

使用场景

如果是位于应用的最上层,或者简单写个脚本只想?一把梭,那用Anyhow就可以了。

ThisError

使用方法

提供了过程宏帮助我们创建自定义的错误类型。他这里的过程宏有点DSL的感觉了。虽然他说他是支持Enum/Struct的,不过感觉大部分情况错误用Enum的和类型比较合适,表达各种各样的错误嘛。

  • #[derive(thiserror::Error)]帮助我们实现std::error::Error
  • #[error("format string")]帮助我们实现Display
  • #[from] xxError帮助我们实现From&lt;xxError&gt;,以及std::error::Error中的source方法。
  • #[source]帮助我们实现std::error::Error中的source方法(返回另一个错误类型,表示产生这个错误的根本原因)。
  • #[backtrace]帮助我们实现std::error::Error中的backtrace方法(貌似是做栈展开之用^backtrace)。
  • #[error(transparent)]帮我我们直接将错误传过来,典型用法是给未定义的错误进行兜底操作。
#[derive(Error, Debug)]
pub enum MyError {
...

#[error(transparent)]
Other(#[from] anyhow::Error),
}

使用场景

需要详细完备的错误信息,又懒得做手动去敲重复代码的重复性工作,比如一些底层库的构建。

举报

相关推荐

0 条评论