1 unstable release
| 0.1.0 | Oct 14, 2025 |
|---|
#280 in Debugging
178 downloads per month
53KB
1K
SLoC
๐ฅ errcraft
"Beautiful Errors. Crafted for Humans and Rustaceans alike."
errcraft is a Rust library that transforms error handling into an elegant, human-centric experience. It provides composable error types with rich context, nested chaining, beautiful CLI rendering, and seamless integration with the Rust ecosystem.
โจ Features
- ๐งฉ Universal Error Type: A composable
ErrFramethat wraps any error with rich context - ๐ฒ Nested Error Trees: Trace errors across layers with perfect indentation
- ๐จ Beautiful CLI Rendering: Colorful, emoji-enhanced output with auto TTY detection
- ๐ง Smart Context: Attach key-value pairs and text annotations
- ๐ Smart Backtraces: Captured conditionally and filtered for clarity
- โ๏ธ Ecosystem Integration: Works with
anyhow,eyre,thiserror,tracing, andaxum - ๐ฆ Serialization: JSON and Markdown output for logs and APIs
- ๐ง Zero Config: Beautiful errors out of the box, customize when needed
๐ Quick Start
Add to your Cargo.toml:
[dependencies]
errcraft = "0.1"
Basic Usage
use errcraft::ErrFrame;
fn read_config(path: &str) -> Result<String, ErrFrame> {
std::fs::read_to_string(path).map_err(|e| {
ErrFrame::new("Failed to read configuration file")
.context("path", path)
.context("operation", "read")
.with_source(e)
})
}
fn main() {
if let Err(e) = read_config("config.toml") {
e.eprint(); // Beautiful error output!
}
}
Output:
โ Error: Failed to read configuration file
๐ฆ Context:
path = config.toml
operation = read
โ ๏ธ Caused by:
โโ No such file or directory (os error 2)
Using Macros
use errcraft::{craft, bail, ensure};
fn process_data(value: i32) -> Result<(), errcraft::ErrFrame> {
ensure!(value > 0, "Value must be positive, got {}", value);
if value > 100 {
bail!("Value too large: {}", value);
}
Ok(())
}
Nested Errors
use errcraft::ErrFrame;
fn deep_function() -> Result<(), std::io::Error> {
Err(std::io::Error::new(
std::io::ErrorKind::NotFound,
"Configuration file not found",
))
}
fn middle_function() -> Result<(), ErrFrame> {
deep_function().map_err(|e| {
ErrFrame::new("Failed to load configuration")
.context("layer", "middleware")
.with_source(e)
})
}
fn top_function() -> Result<(), ErrFrame> {
middle_function().map_err(|e| {
ErrFrame::new("Application initialization failed")
.context("phase", "startup")
.with_source(e)
})
}
๐จ Customization
Display Options
use errcraft::{DisplayOptions, ColorMode, BacktraceMode};
let opts = DisplayOptions::new()
.with_emoji(true)
.with_color(ColorMode::Always)
.with_max_depth(Some(5))
.with_backtrace(BacktraceMode::Shown);
let output = error.to_string_styled(&opts);
println!("{}", output);
Environment Variables
NO_COLOR: Disable colorsRUST_BACKTRACE=1: Show backtraces
๐งฉ Feature Flags
std(default): Standard library supportbacktrace(default): Capture and display backtracescolors-owo(default): Colorful output viaowo-colorscolors-yansi: Alternative color backendcolors-anstyle: Alternative color backendemoji: Enable emoji glyphs in outputserde: JSON serialization supportmarkdown: Markdown renderinganyhow: Integration withanyhoweyre: Integration witheyrethiserror: Integration withthiserrortracing: Integration withtracingaxum: Integration withaxumweb framework
Note: Only one colors-* feature can be enabled at a time.
๐ Examples
Check out the examples directory:
simple.rs- Basic error creation and displaynested.rs- Nested error chainsasync_api.rs- Async context usagecli_output.rs- Output customization
Run an example:
cargo run --example simple
cargo run --example nested
cargo run --example cli_output --all-features
๐ง Integration Examples
With Axum
use errcraft::ErrFrame;
use axum::{routing::get, Router};
async fn handler() -> Result<String, ErrFrame> {
Err(ErrFrame::new("Something went wrong")
.context("endpoint", "/api/v1/data"))
}
let app = Router::new().route("/", get(handler));
With Tracing
use errcraft::ErrFrame;
let err = ErrFrame::new("Database error")
.context("table", "users");
err.trace_error(); // Logs to tracing
With Serde
let err = ErrFrame::new("API error")
.context("code", 404);
let json = err.to_json_string();
println!("{}", json);
๐งช Testing
Run tests with:
cargo test --all-features
Run tests without default features:
cargo test --no-default-features --features std
๐ Documentation
Full API documentation is available at docs.rs/errcraft.
๐ค Contributing
Contributions are welcome! Please read CONTRIBUTING.md for guidelines.
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments
Inspired by:
anyhow- Ergonomic error handlingeyre- Flexible error reportingthiserror- Derive macros for error typescolor-eyre- Colorful error reports
๐ฌ Contact
Author: Eshan Roy
Organization: Tonmoy Infrastructure
Repository: https://gitlab.com/TIVisionOSS/crates/errcraft
"A well-crafted error message is the best form of documentation."
Dependencies
~0โ2.7MB
~51K SLoC