Expand description
A typed error system with error stacks and source-code location tracking.
The crate provides the ErrorStack trait, which extends
std::error::Error with two methods:
stack_source returning the next typed
link in the error chain, and location
returning the source-code location where the error was constructed.
The trait is mainly used via #[derive(ErrorStack)], which implements
ErrorStack based on field names and attributes. The macro also
generates helper constructors that automatically capture the call-site
location, and when a source field is present return a closure allowing
ergonomic chaining with Result::map_err.
An ErrorStack can be converted into a Report, which walks the
full typed chain and produces a traceback with source-code locations.
§Motivation
Error::source only exposes causes as
&dyn Error, so concrete types and any extra context they carry are
lost. Backtraces show where code was running, not where errors were
constructed. errorstack fills this gap by recording the source-code
location of each error and preserving the full typed chain, so every
cause and its origin are available for inspection or display.
§Quick start
use errorstack::{ErrorStack, Report};
#[derive(thiserror::Error, ErrorStack, Debug)]
pub enum AppError {
#[error("io failed: {path}")]
Io {
path: String,
source: std::io::Error,
#[location]
location: &'static std::panic::Location<'static>,
},
#[error("config failed")]
Config {
#[stack_source]
source: ConfigError,
#[location]
location: &'static std::panic::Location<'static>,
},
}
#[derive(thiserror::Error, ErrorStack, Debug)]
#[error("invalid config: {detail}")]
pub struct ConfigError {
detail: String,
#[location]
location: &'static std::panic::Location<'static>,
}
fn load_config() -> Result<(), AppError> {
let inner = ConfigError::new("missing field `port`".into());
Err(AppError::config()(inner))
}
let err = load_config().unwrap_err();
let report = Report::new(&err);
assert_eq!(report.entries().count(), 2);Printing report produces output similar to:
Error: config failed
at src/main.rs:14:9
Caused by this error:
1: invalid config: missing field `port`
at src/main.rs:13:17§Core concepts
§The ErrorStack trait
ErrorStack extends Error with two methods:
-
locationreturns thestd::panic::Locationwhere the error was constructed, orNoneif location tracking is not present for that error. -
stack_sourcereturns the nextErrorStackimplementor in the chain, orNoneif the error is the root cause or if the underlying source does not implementErrorStack.
The trait is typically derived rather than implemented by hand. See the derive macro documentation for the full attribute reference, naming conventions, and generated constructor signatures.
§Report
Report collects an entire error chain into a list of Entry
values, each pairing an error message with a source-code
location where available.
Report provides a default Display
implementation that renders the chain in a human-readable format with
the outermost error first, followed by numbered causes and their
locations. Callers that need a different structure (for example,
emitting each frame as a structured telemetry event) can iterate over
the Entry values directly via Report::entries.
§Compatibility with thiserror
errorstack uses the same field conventions as
thiserror and is designed to
pair with it.
Structs§
- Entry
- A single entry in an error report, pairing an error message with an
optional source-code
Location. - Report
- A collected summary of an entire error chain, suitable for display or structured inspection.
Traits§
- Error
Stack - An error within a typed error stack, preserving full error context as errors propagate up the call stack.
Derive Macros§
- Error
Stack - Derive macro for
ErrorStack.