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()或Fromtrait 以保持兼容性,任何剩余的方法——注意,后续使用?操作符将不再被跟踪。要完全丢弃调用栈,也可以使用TracedResult::discard_call_stack()来获取一个不带TracedError包装器围绕E的Result<T, E>
注意:#[track_caller] 属性
内部,TracedResult 使用 #[track_caller] 属性来获取使用 ? 操作符的位置。这意味着如果结果是从一个本身带有 #[track_caller] 注解的函数中传播的,则添加到调用栈的 Location 将是函数调用者的位置,而不是 Try 操作符本身的位置。