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 日 |
#277 在 Rust 模式
每月 23 次下载
用于 5 个 crate (3 个直接使用)
31KB
422 行
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(LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT许可证(LICENSE-MIT 或 https://opensource.org/licenses/MIT)
由您选择。
贡献
除非您明确声明,否则您有意提交以供包含在作品中的任何贡献,如Apache-2.0许可证所定义,应按照上述方式双重许可,无需附加条款或条件。