18 个版本 (1 个稳定版)

1.0.0 2023 年 7 月 28 日
0.8.2 2023 年 7 月 28 日
0.7.1 2023 年 7 月 27 日
0.7.0 2021 年 2 月 2 日
0.2.0 2018 年 12 月 21 日

#277Rust 模式

每月 23 次下载
用于 5 个 crate (3 个直接使用)

MIT/Apache

31KB
422

Crate Rust Documentation Coverage Status Maintenance

chainerror

chainerror 提供了一个错误回溯,而不进行实际的回溯,所以即使你在二进制文件中 strip,你仍然有错误回溯。

当嵌套函数返回错误时,输出不会说明错误起源于何处。

use std::path::PathBuf;

type BoxedError = Box<dyn std::error::Error + Send + Sync>;
fn read_config_file(path: PathBuf) -> Result<(), BoxedError> {
    // do stuff, return other errors
    let _buf = std::fs::read_to_string(&path)?;
    // do stuff, return other errors
    Ok(())
}

fn process_config_file() -> Result<(), BoxedError> {
    // do stuff, return other errors
    let _buf = read_config_file("foo.txt".into())?;
    // do stuff, return other errors
    Ok(())
}

fn main() {
    if let Err(e) = process_config_file() {
        eprintln!("Error:\n{:?}", e);
    }
}

这将给出以下输出

Error:
Os { code: 2, kind: NotFound, message: "No such file or directory" }

而你没有线索知道它来自哪里。

使用 chainerror,你可以提供上下文并获得一个漂亮的错误回溯

use chainerror::Context as _;
use std::path::PathBuf;

type BoxedError = Box<dyn std::error::Error + Send + Sync>;
fn read_config_file(path: PathBuf) -> Result<(), BoxedError> {
    // do stuff, return other errors
    let _buf = std::fs::read_to_string(&path).context(format!("Reading file: {:?}", &path))?;
    // do stuff, return other errors
    Ok(())
}

fn process_config_file() -> Result<(), BoxedError> {
    // do stuff, return other errors
    let _buf = read_config_file("foo.txt".into()).context("read the config file")?;
    // do stuff, return other errors
    Ok(())
}

fn main() {
    if let Err(e) = process_config_file() {
        eprintln!("Error:\n{:?}", e);
    }
}

输出如下

Error:
examples/simple.rs:14:51: read the config file
Caused by:
examples/simple.rs:7:47: Reading file: "foo.txt"
Caused by:
Os { code: 2, kind: NotFound, message: "No such file or directory" }

chainerror 使用 .source()std::error::Error 以及 #[track_caller]Location 来提供漂亮的调试错误回溯。它封装了所有具有 Display + Debug 的类型,并可以内部存储错误原因。

除了 Error<T> 结构体之外,chainerror 还附带了一些有用的辅助宏,可以节省大量打字。

chainerror 没有任何依赖!

调试信息是值得的!

多种输出格式

chainerror 支持多种输出格式,可以通过不同的格式说明符进行选择

  • {}: 显示
func1 error calling func2
  • {:#}: 替代显示
func1 error calling func2
Caused by:
  func2 error: calling func3
Caused by:
  (passed error)
Caused by:
  Error reading 'foo.txt'
Caused by:
  entity not found
  • {:?}: 调试
examples/example.rs:50:13: func1 error calling func2
Caused by:
examples/example.rs:25:13: Func2Error(func2 error: calling func3)
Caused by:
examples/example.rs:18:13: (passed error)
Caused by:
examples/example.rs:13:18: Error reading 'foo.txt'
Caused by:
Kind(NotFound)

  • {:#?}: 替代调试
Error<example::Func1Error> {
    occurrence: Some(
        "examples/example.rs:50:13",
    ),
    kind: func1 error calling func2,
    source: Some(
        Error<example::Func2Error> {
            occurrence: Some(
                "examples/example.rs:25:13",
            ),
            kind: Func2Error(func2 error: calling func3),
            source: Some(
                Error<chainerror::AnnotatedError> {
                    occurrence: Some(
                        "examples/example.rs:18:13",
                    ),
                    kind: (passed error),
                    source: Some(
                        Error<alloc::string::String> {
                            occurrence: Some(
                                "examples/example.rs:13:18",
                            ),
                            kind: "Error reading 'foo.txt'",
                            source: Some(
                                Kind(
                                    NotFound,
                                ),
                            ),
                        },
                    ),
                },
            ),
        },
    ),
}

教程

阅读 教程

许可

许可协议之一

由您选择。

贡献

除非您明确声明,否则您有意提交以供包含在作品中的任何贡献,如Apache-2.0许可证所定义,应按照上述方式双重许可,无需附加条款或条件。

无运行时依赖