traced_error
Typed errors with automatic trace frames and structured context for Rust error propagation.
traced_error keeps the original typed error body while recording where errors are propagated through ?.
It is useful when you want debugging context similar to anyhow, but still need to match concrete error variants and inspect structured fields.
Why
Rust's ? operator propagates errors, but it does not automatically record the source location where propagation happened.
Libraries such as anyhow are excellent for application-level error reports, but they erase the concrete error type behind a dynamic report.
traced_error separates these two concerns:
Traced<E>keepsEas the typed error body.- The
#[traced]macro appends source locations for each rewritten?. .ctx(...)and.with_ctx(...)attach explicit displayable context payloads.
Features
- Preserve typed error bodies instead of converting everything into a string report.
- Automatically append source locations for
?propagation through the#[traced]macro. - Attach explicit structured context with
.ctx(...)and.with_ctx(...). - Lift raw
Result<T, E>values intoResult<T, Traced<E>>with.ctx_lift(...)and.with_ctx_lift(...). - Keep traces and context across error type conversions.
- Implement
std::error::ErrorforTraced<E>whenEis an error, exposing the typed body assource(). - Use
SmallVecto avoid heap allocation for short trace/context stacks.
Install
[]
= "0.1"
= "1"
You normally only depend on traced_error directly. The companion proc-macro crate traced_macro is re-exported by traced_error.
Example
use ParseIntError;
use *;
The error still contains MyError, so callers can continue to match on typed variants when needed.
When the typed error body implements std::error::Error, Traced<E> also implements std::error::Error and exposes the inner typed error through source().
Comparison with tracing-error
This crate solves a different problem from tracing-error.
tracing-error captures the current tracing span context and attaches it to errors through SpanTrace and TracedError. It is a good fit when your application is already instrumented with tracing spans and you want span-aware diagnostics.
traced_error records source locations of ? propagation points by rewriting them in the #[traced] procedural macro. It is a good fit when you want typed errors with automatic file/line/column traces showing where errors were propagated.
In short:
- use
tracing-errorwhen you want span-aware diagnostics in atracing-instrumented application; - use
traced_errorwhen you want typed errors with automatic file/line/column traces for?propagation.
The two crates can also be complementary: tracing-error tells you the active span context, while traced_error tells you the concrete ? propagation path.
Workspace layout
This repository contains two crates:
| Crate | Purpose |
|---|---|
traced_error |
Public runtime API: Traced, context traits, prelude, and macro re-export. |
traced_macro |
Proc-macro implementation for #[traced]. |
traced_macro does not need a separate GitHub repository. It can be published as a separate crates.io package while living in the same GitHub workspace repository.
The publish order matters because traced_error depends on traced_macro:
Repository metadata
Both crates can point to the same repository:
= "https://github.com/lihaohan/traced_error"
= "https://github.com/lihaohan/traced_error"
There is no requirement to create https://github.com/lihaohan/traced_macro unless you want to maintain the macro crate independently.
License
Licensed under either of MIT or Apache-2.0 at your option.