1 个不稳定版本
0.1.0 | 2024年7月25日 |
---|
#627 在 Rust 模式
每月下载 127 次
13KB
192 行
traced_result
一个概念验证,用于自动回溯使用 ?
操作符传播的错误
注意:此 crate 依赖于不稳定语言特性 try_trait_v2
。这意味着它只能与 nightly
工具链一起使用,可能随时会中断,因此不建议在生产代码中使用,直到该特性稳定。
用法
traced_result
与像 trace_error
这样的 crate 不同,因为它不使用宏来跟踪调用堆栈,而是使用(目前不稳定)的 Try
特性尽可能与常规 Result
保持一致。此 crate 的核心类型是 TracedResult<T, E>
,设计用来像 std::result::Result<T, E>
一样工作,以及 TracedError<E>
,它只是 E
的包装和一个 Vec<&'static Location<'static>>
。要开始,只需将 Result
替换为 TracedResult
// From
fn foo() -> Result<Bar, Baz> {
// ...
return Err(Baz(/*...*/));
}
// To
fn foo() -> TracedResult<Bar, Baz> {
// ...
return TracedResult::Err(TracedError::new(Baz(/*...*/)))
}
TracedResult
和 TracedError
还提供了方便的 From
实现,允许你编写如下内容
return TracedResult::Err(Baz(/*...*/).into())
或者甚至
return Err(Baz(/*...*/)).into()
现在,每当使用 ?
操作符传播 TracedResult
时,TracedResult
的 Try
实现将存储操作符使用位置到错误的调用堆栈中(如果有的话)
fn foo() -> TracedResult<Bar, Baz> {
Err(Baz(/*...*/)).into()
}
fn do_something() -> TracedResult<(), Baz> {
let value = foo()?;
Ok(())
}
fn main() {
if let TracedResult::Err(error) = do_something() {
println!("{}", error)
// Baz at (40:21) in file example.rs
// at (2:26) in file example.rs
}
}
Result
方法
TracedResult<T, E>
目前有以下方法
unwrap()
及所有相关方法,包括unchecked
方法is_ok()
和is_err()
map()
及所有相关方法- 转换为
std::result::Result<T, TracedError<E>>
使用into_result()
或From
trait 以保持兼容性,任何剩余的方法——注意,后续使用?
操作符将不再被跟踪。要完全丢弃调用栈,也可以使用TracedResult::discard_call_stack()
来获取一个不带TracedError
包装器围绕E
的Result<T, E>
注意:#[track_caller]
属性
内部,TracedResult
使用 #[track_caller]
属性来获取使用 ?
操作符的位置。这意味着如果结果是从一个本身带有 #[track_caller]
注解的函数中传播的,则添加到调用栈的 Location
将是函数调用者的位置,而不是 Try
操作符本身的位置。