Suzunari Error
A highly traceable and noise-free error handling library for Rust. Propagates error locations as error contexts and minimizes information output to logs.
Built on SNAFU, inspired by Error Handling for Large Rust Projects - Best Practice in GreptimeDB and tamanegi-error.
Features
#[suzunari_error]— The primary macro. Annotate your error type and getSnafu+StackErrorderives plus automaticlocationfield injection. Supports#[suzu(...)]attributes for snafu passthrough and suzunari extensions (from,location).StackErrortrait — Error location-aware contextual chained errors. Provideslocation(),type_name(),stack_source(), anddepth()for traversing error chains with location info.StackReport— Formats aStackErrorchain as a stack-trace-like report with type names and locations at each level. Use at error display boundaries.Location— Memory-efficient location structure compatible with SNAFU's implicit context.DisplayError<E>— Adapter to wrap external types that implementDebug + Displaybut notError, making them usable as snafusourcefields.BoxedStackError— Type-erasedStackErrorwrapper for uniform error handling across module boundaries (requiresalloc).#![no_std]compatible — Works in core-only,alloc, andstdenvironments via feature flags.
Usage
Note: The examples below use
std::io::Errorand require the defaultstdfeature. Forno_stdusage, see Feature Flags.
use suzunari_error::* brings in everything you need — macros, traits (ResultExt, OptionExt), and the ensure! macro. No need to add snafu as a direct dependency.
use *;
Snafu selector types:
#[suzunari_error](via snafu) generates context selector types named<VariantOrType>Snafu— e.g.,ReadTimeoutSnafufor theReadTimeoutvariant,RetrieveFailedSnafufor theRetrieveFailedstruct. These selectors are used with.context()to attach error context at each call site. See the snafu user guide for details.
StackReport — Formatted error chain output
Use StackReport at error display boundaries to produce stack-trace-like output:
use *;
#
#
#
#
#
#
#[suzunari_error::report] — Simplified main with error reporting
Use #[suzunari_error::report] on main() to automatically convert the return type to StackReport<E>, which prints a formatted error chain to stderr and exits with a non-zero code on failure:
use *;
#
#
#
#
This is equivalent to snafu::report but uses StackReport for location-aware output.
BoxedStackError — Uniform error handling across module boundaries
use *;
DisplayError — Wrapping non-Error types
For third-party types that implement Debug + Display but not Error, use #[suzu(from)] to automatically wrap the type in DisplayError and generate the source(from(...)) annotation:
use *;
// A third-party type: Debug + Display but no Error impl
;
This expands to the equivalent manual form:
# use *;
#
# ;
#
#[suzu(...)] vs #[snafu(...)]
#[suzu(...)] is a superset of #[snafu(...)]. All snafu keywords (display, source, implicit, etc.) work inside #[suzu(...)] and are passed through to snafu. Additionally, #[suzu(...)] supports from and location extensions.
When using #[suzunari_error], prefer #[suzu(...)] over #[snafu(...)] for consistency. #[snafu(...)] also works but mixing the two styles is discouraged.
Feature Flags
| Feature | Default | Description |
|---|---|---|
std |
Yes | Enables alloc + snafu/std + StackReport's Termination impl + #[report] macro |
alloc |
No | Enables BoxedStackError and From<T> for BoxedStackError macro generation |
| (none) | — | Core-only: Location, StackError, StackReport (formatting only), DisplayError |
Note:
StackReportitself uses onlycore::fmtand is available in all tiers. Only theTerminationimpl (for use asmain()return type) and#[report]requirestd.
For no_std usage, disable default features:
[]
= { = "0.1", = false }
Why suzunari-error?
Standard Rust error approaches have a tradeoff between traceability and ergonomics:
| Approach | Per-level location | Auto-capture | Type-safe chain | no_std |
|---|---|---|---|---|
thiserror |
- | - | Yes | Yes |
anyhow/eyre |
Single backtrace | Yes | - | - |
snafu alone |
Manual | Manual | Yes | Yes |
| suzunari-error | Automatic | Yes | Yes | Yes (3 tiers) |
suzunari-error builds on snafu to add what's missing: automatic per-error-level location tracking via #[track_caller], a structured StackReport formatter that shows type names and locations at each level, and ergonomic macros (#[suzunari_error], #[suzu(from)]) that reduce boilerplate.
See examples/ for runnable demonstrations.
Known Issues
- When using
#[suzunari_error]without a wildcard import, IntelliJ IDEA may report false compile errors.cargo build/cargo testwill succeed. Workaround:use suzunari_error::*;
License
Licensed under either of Apache License, Version 2.0 or MIT License at your option.