# ๐ฅ errcraft
**"Beautiful Errors. Crafted for Humans and Rustaceans alike."**
[](https://crates.io/crates/errcraft)
[](https://docs.rs/errcraft)
[](https://opensource.org/licenses/MIT)
[](https://gitlab.com/TIVisionOSS/crates/errcraft/-/pipelines)
`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`:
```toml
[dependencies]
errcraft = "0.1"
```
### Basic Usage
```rust
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
```rust
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
```rust
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
```rust
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](./examples) directory:
- [`simple.rs`](./examples/simple.rs) - Basic error creation and display
- [`nested.rs`](./examples/nested.rs) - Nested error chains
- [`async_api.rs`](./examples/async_api.rs) - Async context usage
- [`cli_output.rs`](./examples/cli_output.rs) - Output customization
Run an example:
```bash
cargo run --example simple
cargo run --example nested
cargo run --example cli_output --all-features
```
## ๐ง Integration Examples
### With Axum
```rust
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
```rust
use errcraft::ErrFrame;
let err = ErrFrame::new("Database error")
.context("table", "users");
err.trace_error(); // Logs to tracing
```
### With Serde
```rust
let err = ErrFrame::new("API error")
.context("code", 404);
let json = err.to_json_string();
println!("{}", json);
```
## ๐งช Testing
Run tests with:
```bash
cargo test --all-features
```
Run tests without default features:
```bash
cargo test --no-default-features --features std
```
## ๐ Documentation
Full API documentation is available at [docs.rs/errcraft](https://docs.rs/errcraft).
## ๐ค Contributing
Contributions are welcome! Please read [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
## ๐ License
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
## ๐ Acknowledgments
Inspired by:
- [`anyhow`](https://github.com/dtolnay/anyhow) - Ergonomic error handling
- [`eyre`](https://github.com/eyre-rs/eyre) - Flexible error reporting
- [`thiserror`](https://github.com/dtolnay/thiserror) - Derive macros for error types
- [`color-eyre`](https://github.com/eyre-rs/color-eyre) - Colorful error reports
## ๐ฌ Contact
**Author**: Eshan Roy
**Organization**: Tonmoy Infrastructure
**Repository**: [https://gitlab.com/TIVisionOSS/crates/errcraft](https://gitlab.com/TIVisionOSS/crates/errcraft)
---
*"A well-crafted error message is the best form of documentation."*