errcraft

Crates.ioerrcraft
lib.rserrcraft
version0.1.0
created_at2025-10-14 16:54:33.716408+00
updated_at2025-10-14 16:54:33.716408+00
descriptionBeautiful, structured, and colorful error handling for Rust.
homepage
repositoryhttps://gitlab.com/TIVisionOSS/crates/errcraft
max_upload_size
id1882728
size111,026
Eshan Roy (eshanized)

documentation

https://docs.rs/errcraft

README

๐Ÿ’ฅ errcraft

"Beautiful Errors. Crafted for Humans and Rustaceans alike."

Crates.io Documentation License: MIT CI

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 ErrFrame that 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, and axum
  • ๐Ÿ“ฆ 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 colors
  • RUST_BACKTRACE=1: Show backtraces

๐Ÿงฉ Feature Flags

  • std (default): Standard library support
  • backtrace (default): Capture and display backtraces
  • colors-owo (default): Colorful output via owo-colors
  • colors-yansi: Alternative color backend
  • colors-anstyle: Alternative color backend
  • emoji: Enable emoji glyphs in output
  • serde: JSON serialization support
  • markdown: Markdown rendering
  • anyhow: Integration with anyhow
  • eyre: Integration with eyre
  • thiserror: Integration with thiserror
  • tracing: Integration with tracing
  • axum: Integration with axum web framework

Note: Only one colors-* feature can be enabled at a time.

๐Ÿ“š Examples

Check out the examples directory:

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 handling
  • eyre - Flexible error reporting
  • thiserror - Derive macros for error types
  • color-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."

Commit count: 0

cargo fmt