Stacked Errors
A crate for high level error propogation with programmed backtraces.
In Rust development, major crates will often have their own error enums that
work well in their own specialized domain, but when orchestrating many
domains together we run into issues. map_err
is very annoying to work
with. In async
call stacks we run into an especially annoying problem
where the same kind of error can be returned from multiple places, and we
are sometimes forced into println
debugging to find out where it is
actually from. This crate introduces the StackableErr
trait and a
"stackable" error type that allows for both software-defined error
backtraces and easily converting errors into the stackable error type.
Some partial examples of what using the crate looks like:
f.map_err?;
// replace the above with
f.stack?; // uses `#[track_caller]` when an error is being propagated
let dir = self
.path
.parent
.stack_err?
.to_str
.stack_err?;
// if needing to push another arbitrary error onto the stack
f.stack_err?;
option.take
.stack_err?
.wait_with_output
.await
.stack_err?;
// strings and some std errors can be created like this,
return Err
// otherwise use this (also note that `Error::from*` includes
// `#[track_caller]` location, no need to add on a `stack` call)
return Err
// when the error type is already `stacked_errors::Error` you can do this if it is
// preferable over `map`
return match ...
use ;
// Note that `Error` uses `ThinVec` internally, which means that it often
// takes up only the stack space of a `usize` or the size of the `T` plus
// a byte.
let res = format!;
assert_eq!;
// The line numbers are slightly off because this is a doc test.
// In order from outer to the innermost call, it lists the location of the
// `stack` call from `outer`, the location of `stack_err` from `inner`,
// the associated error message, the location of either the `Error::from`
// or `stack_err` from `innermost`, and finally the root error message.
let res = format!;
assert_eq!;
let res = format!;
assert_eq!;
Also remember that .stack_err(|| ())
is equivalent to .stack()
// in commonly used functions you may want `_locationless` to avoid adding
// on unnecessary information if the location is already being added on
return Err.stack_err