Expand description
§pseudo-backtrace
This is a library that makes it easy to create error types that can track error propagation history.
§Example
use pseudo_backtrace::{StackError, StackErrorExt};
#[derive(Debug)]
pub struct ErrorA(());
impl core::fmt::Display for ErrorA {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
"ErrorA".fmt(f)
}
}
impl core::error::Error for ErrorA {}
#[derive(Debug, StackError)]
pub struct ErrorB {
#[stack_error(std)]
source: ErrorA,
location: &'static core::panic::Location<'static>,
}
impl core::fmt::Display for ErrorB {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
"ErrorB".fmt(f)
}
}
impl core::error::Error for ErrorB {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.source)
}
}
impl From<ErrorA> for ErrorB {
#[track_caller]
fn from(value: ErrorA) -> Self {
ErrorB {
source: value,
location: core::panic::Location::caller(),
}
}
}
#[derive(Debug, StackError)]
pub struct ErrorC {
source: ErrorB,
location: &'static core::panic::Location<'static>,
}
impl core::fmt::Display for ErrorC {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
"ErrorC".fmt(f)
}
}
impl core::error::Error for ErrorC {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.source)
}
}
impl From<ErrorB> for ErrorC {
#[track_caller]
fn from(value: ErrorB) -> Self {
ErrorC {
source: value,
location: core::panic::Location::caller(),
}
}
}
let a = ErrorA(());
let b = ErrorB::from(a);
let c = ErrorC::from(b);
println!("{}", c.to_chain())
// will be printed to standard output as follows:
// 0: ErrorC, at examples/simple.rs:74:13
// 1: ErrorB, at examples/simple.rs:73:13
// 2: ErrorA
§Using #[derive(StackError)]
Deriving StackError
requires two types of fields:
-
Required Field:
- A field holding a
&'static core::panic::Location<'static>
. This is mandatory. - The field can be named
location
or marked with the#[location]
attribute.
- A field holding a
-
Optional Field:
- A field representing the next error in the stack trace. This field is optional.
- It can be marked with either:
#[stack_error(std)]
: Treats the next error as a type implementingcore::error::Error
.#[stack_error(stacked)]
: Treats the next error as a type implementingStackError
.#[source]
or a field namedsource
: Defaults to#[stack_error(stacked)]
.
Note that the macro only implements StackError
, so users must manually implement core::error::Error
.
§Using LocatedError
as both location
and source
You can embed a LocatedError<T>
field and use it for both the location
and the source
in one of the following ways:
- Explicitly mark the same field with both attributes:
#[derive(Debug, pseudo_backtrace::StackError)]
pub struct WrappedIo {
#[location]
#[source] // or `#[stack_error(stacked)]` / `#[stack_error(std)]`
inner: pseudo_backtrace::LocatedError<std::io::Error>,
}
impl core::fmt::Display for WrappedIo {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "wrapped-io")
}
}
impl core::error::Error for WrappedIo {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.inner)
}
}
- Or, if you omit an explicit
#[location]
, the derive will automatically use the#[source]
field when its type isLocatedError<_>
as the location provider:
#[derive(Debug, pseudo_backtrace::StackError)]
pub struct WrappedIo {
#[source]
inner: pseudo_backtrace::LocatedError<std::io::Error>,
}
impl core::fmt::Display for WrappedIo {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "wrapped-io")
}
}
impl core::error::Error for WrappedIo {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.inner)
}
}
In both cases, the generated impl StackError
will return inner.location()
as the location and will chain to inner
as the next error.
Structs§
- Chain
Writer - Helper for display Chain
- Iter
- Iterator over individual error stack entries.
- Located
Error - Wrapper that records the call-site for any
core::error::Error
and exposes it as a StackError.
Enums§
- Chain
- One layer in a stack of chained errors.
Traits§
- Stack
Error - Error types that can report a stack trace-like chain.
- Stack
Error Ext - Convenience helpers for types implementing StackError.