Crates.io | traced_result |
lib.rs | traced_result |
version | 0.1.0 |
source | src |
created_at | 2024-07-25 16:28:47.512303 |
updated_at | 2024-07-25 16:28:47.512303 |
description | Proof-of-concept error tracing using the `Try` trait |
homepage | |
repository | |
max_upload_size | |
id | 1315237 |
size | 14,005 |
?
operator#Note: This crate relies on the unstable try_trait_v2
language feature. This means it can only be used with the nightly
toolchain, may break at any time, and is thus not recommended for use in production code until this feature is stabilized.
traced_result
differs from crates like trace_error
in that it does not use macros to trace call stacks, but instead uses the (currently unstable) Try
trait to be as consistent with regular Result
s as possible.
The two types at the core of this crate are TracedResult<T, E>
, designed to work like std::result::Result<T, E>
, and TracedError<E>
, which is simply a wrapper around E
and a Vec<&'static Location<'static>>
. To get started, simply replace Result
with TracedResult
:
// From
fn foo() -> Result<Bar, Baz> {
// ...
return Err(Baz(/*...*/));
}
// To
fn foo() -> TracedResult<Bar, Baz> {
// ...
return TracedResult::Err(TracedError::new(Baz(/*...*/)))
}
TracedResult
and TracedError
also come with convenient From
implementations, allowing you to write something like
return TracedResult::Err(Baz(/*...*/).into())
or even
return Err(Baz(/*...*/)).into()
Now, whenever a TracedResult
is propagated with the ?
operator, TracedResult
's Try
impl will store the location of the operators usage to the errors call stack, if any:
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
methodsTracedResult<T, E>
currently has its the following methods:
unwrap()
and all related methods, including the unchecked
methodsis_ok()
and is_err()
map()
and all related methodsstd::result::Result<T, TracedError<E>>
using into_result()
or the From
trait for compatibility any remaining methods – note that subsequent uses of the ?
operator will no longer be tracked. To discard the call stack completely, you can also use TracedResult::discard_call_stack()
to get a Result<T, E>
without the TracedError
wrapper around E
.#[track_caller]
attributeInternally, TracedResult
uses the #[track_caller]
attribute to get the location at which the ?
operator was used. This means that if the result is propagated from a function which itself is annotated with #[track_caller]
, the Location
added to the call stack will be that of the function's caller, not that of the Try
operator itself.