9 个不稳定版本 (3 个重大更新)

0.4.5 2023年2月9日
0.4.4 2023年1月23日
0.4.3 2022年11月24日
0.3.0 2022年11月24日
0.1.0 2022年4月24日

调试 分类中排名第200

Download history 10/week @ 2024-04-03

每月下载量103

MIT 许可协议

37KB
913

Cadom

Rust 的错误处理助手

名称

该项目具有自动生成的名称,归功于 This Word Does Not Exist 项目。单词定义可以在 此处 检查。

目的

该项目的整体目的是使错误处理过程更加简单。其思路是提供有关错误发生的信息,包括整个回溯,同时避免代码和输出中的不必要的冗余。所谓的“不必要的冗余”是一个完全主观的概念,因此人们可能会对结果表示不同意见。人们可能会陷入在为每种处理的底层错误使用 thiserror,无论什么情况下使用 anyhow 来处理所有错误,以及自定义实现来收集错误跟踪信息(至少在 std::backtrace::Backtrace 仍处于实验性阶段的情况下)。在这种情况下,Cadom 应该是最佳选择。

使用示例

Cadom 建议在 thiserroranyhow 和手动 Error 实现之间选择。假设已经描述了自己的类型 Origin,它收集了应用程序中处理的所有其他错误类型(可能通过 thiserror 实现),但仍难以添加跟踪信息。通过 cadom 可以轻松实现。

#[derive(thiserror::Error, Clone, Debug, PartialEq, Eq)]
enum FailKind {
    #[error(transparent)]
    ParseInt(#[from] std::num::ParseIntError),
    #[error("{0}")]
    Custom(String),
}

impl From<String> for FailKind {
    fn from(src: String) -> Self {
        FailKind::Custom(src)
    }
}

type Fail = cadom::Decay<FailKind>;

fn parse_u8(text: &str) -> Result<u8, std::num::ParseIntError> {
    text.parse::<u8>()
}

fn do_something() -> Result<(), String> {
    Err("Unimplemented functionality".into())
}

fn do_something_else(opt_text: Option<&str>) -> Result<(), Fail> {
    match opt_text {
        Some(text @ "Dramatically unsuitable text") => Err(cadom::decay!("Passed text ('{}') is soooo unsuitable it generated a special error", text)),
        Some(text) => parse_u8(text).map_err(cadom::rot!("Passed text can`t be parsed as u8")).map(|_| ()),
        None => do_something().map_err(cadom::rot!())
    }
}

fn main() {
    let err_1: Fail = do_something_else(Some("Dramatically unsuitable text")).map_err(cadom::rot!()).unwrap_err();
    println!("{}", err_1);
    let err_2: Fail = do_something_else(Some("Not so unsuitable text, but still not a number")).map_err(cadom::rot!()).unwrap_err();
    println!("{}", err_2);
    let err_3: Fail = do_something_else(None).map_err(cadom::rot!("No data were passed into function")).unwrap_err();
    println!("{}", err_3);
}

这里使用的 FailKind 类型将所有必要的“外部”错误类型转换为具有适当 类型相关 注释的类型,而 Fail 类型则表示具有添加在每个需要的地方的 位置相关 注释的应用程序错误的多级版本。当使用宏 deacayrot 时,这些注释会自动用文件:行:列格式的位置信息丰富。上面的例子给出了以下输出

{place: [src/main.rs:34:87, src/main.rs:27:60], note: Passed text ('Dramatically unsuitable text') is soooo unsuitable it generated a special error}
{place: [src/main.rs:36:104, src/main.rs:28:46], note: Passed text can`t be parsed as u8, error: invalid digit found in string}
{place: [src/main.rs:38:55], note: No data were passed into function, place: [src/main.rs:29:40], error: Unimplemented functionality}

正如所见,由于使用了decayrot宏,在程序执行过程中(从错误变成失败类型的那一刻起),每个地方发生的错误信息都会被添加到该错误中。不幸的是,通常需要提供错误类型注释,但这被认为不是一个问题,因为建议的方法使用的是最终类型,这应该由应用程序本身指定(如上面示例中的Fail)。为了满足示例,以下是示例输出的美化版本

{
    place: [src/main.rs:34:87, src/main.rs:27:60],
    note: Passed text ('Dramatically unsuitable text') is soooo unsuitable it generated a special error,
}
{
    place: [src/main.rs:36:104, src/main.rs:28:46],
    note: Passed text can`t be parsed as u8,
    error: invalid digit found in string,
}
{
    place: [src/main.rs:38:55],
    note: No data were passed into function,
    place: [src/main.rs:29:40],
    error: Unimplemented functionality,
}

依赖项

~44–520KB
~10K SLoC