掘金 后端 ( ) • 2024-04-24 10:15

本教程环境

系统:MacOS

Rust 版本:1.77.2

thiserror

thiserror crate 为标准库的 std::error::Error trait 提供了一系列的派生宏。使用这个库可以更加方便快捷的定义自定义错误类型。

pub trait Error: Debug + Display {
    // Provided methods
    fn source(&self) -> Option<&(dyn Error + 'static)> { ... }
    fn description(&self) -> &str { ... }
    fn cause(&self) -> Option<&dyn Error> { ... }
    fn provide<'a>(&'a self, request: &mut Request<'a>) { ... }
}

通过 Error 的定义可以看到,我们的自定义错误需要实现 ErrorDebugDisplay 这三个trait。 下面是自定义的错误类型自定义的 JsonError

use std::{error::Error, fmt};

#[derive(Debug)]
struct JsonError {
    message: String,
    line: usize,
    column: usize
}

impl fmt::Display for JsonError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}, ({}: {})", self.message, self.line, self.column)
    }
}

impl Error for JsonError {}

是使用 thiserror crate 可以使用宏调用来简化上面的过程。 在项目的 Cargo.toml 文件的 dependencies 中引入 thiserror 依赖。

[dependencies]
thiserror = "1.0.59"

或者在命令行中使用 cargo add thiserror 添加依赖。 接下来使用 thiserror 来定义 JsonError

#[derive(Error, Debug)]
#[error("{message:} ({line}: {column})")]
struct JsonError {
    message: String,
    line: usize,
    column: usize
}

使用了宏之后,可以看到代码更加的简洁。 #[error("{message:} ({line}: {column})")] 用来实现 std::fmt::Display

官方文档: https://crates.io/crates/thiserror

anyhow

在 Rust 中,anyhow crate 是一个提供了易使用的错误处理机制的库。它适用于编写程序时并不关心错误的具体类型,只希望以便捷的方式传播错误。anyhow 提供的是一种类似于 Box<dyn std::error::Error> 的错误类型,并且支持 ? 运算符用于错误的传播。 anyhow 的主要特点是它能够将多种类型的错误统一到一个 anyhow::Error 类型中,从而简化了错误处理。几乎任何类型的错误都可以转换为 anyhow 提供的 Error 类型。 使用 cargo add anyhow 添加 crate。 下面是一个简单的用例。

use anyhow::{bail, Ok, Result};

fn divide(a: i32, b: i32) -> Result<f64> {
    if b == 0 {
        bail!("Cannot divide by zero");
    }
    Ok(a as f64 / b as f64)
}

fn main() -> Result<()> {
    let result = divide(10, 0)?;
    println!("{}", result); // Error: Cannot divide by zero
    Ok(())
}

bail! 宏是 anyhow crate 提供的一个用于立即返回错误的便捷方式。当你想要在某个函数内部遇到错误时立即返回 anyhow::Error,并且希望同时提供一个描述性的错误消息时,bail! 宏就非常有用了。 🌟示例代码仓库:https://github.com/zcfsmile/RustLearning/tree/main/error-handling 🌟 🙏🙏感谢您的阅读,如果对您有帮助,欢迎关注、点赞 🌟🌟