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
每月下载量103次
37KB
913 行
Cadom
Rust 的错误处理助手
名称
该项目具有自动生成的名称,归功于 This Word Does Not Exist 项目。单词定义可以在 此处 检查。
目的
该项目的整体目的是使错误处理过程更加简单。其思路是提供有关错误发生的信息,包括整个回溯,同时避免代码和输出中的不必要的冗余。所谓的“不必要的冗余”是一个完全主观的概念,因此人们可能会对结果表示不同意见。人们可能会陷入在为每种处理的底层错误使用 thiserror,无论什么情况下使用 anyhow 来处理所有错误,以及自定义实现来收集错误跟踪信息(至少在 std::backtrace::Backtrace 仍处于实验性阶段的情况下)。在这种情况下,Cadom 应该是最佳选择。
使用示例
Cadom 建议在 thiserror、anyhow 和手动 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
类型则表示具有添加在每个需要的地方的 位置相关 注释的应用程序错误的多级版本。当使用宏 deacay
或 rot
时,这些注释会自动用文件:行:列格式的位置信息丰富。上面的例子给出了以下输出
{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}
正如所见,由于使用了decay
和rot
宏,在程序执行过程中(从错误变成失败类型的那一刻起),每个地方发生的错误信息都会被添加到该错误中。不幸的是,通常需要提供错误类型注释,但这被认为不是一个问题,因为建议的方法使用的是最终类型,这应该由应用程序本身指定(如上面示例中的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