error-envelope
Structured, traceable, retry-aware HTTP error responses for Rust APIs. Features anyhow and Axum integration with a framework-agnostic core.
Overview
- anyhow integration: Automatic conversion from anyhow::Error into error_envelope::Error at the HTTP boundary
- thiserror mapping: Implement From for explicit HTTP semantics (no accidental 500s)
- Axum support: Implements IntoResponse for seamless API error handling
- Consistent error format: One predictable JSON structure for all HTTP errors
- Typed error codes: 18 standard codes as a type-safe enum
- Traceability: Built-in support for trace IDs and retry hints
- Framework-agnostic core: Works standalone; integrations are opt-in via features
The stack: anyhow for propagation β error-envelope at the HTTP boundary β Axum via axum-support
use ;
use ;
use HashMap;
// Automatic conversion from anyhow:
async
// Structured validation errors:
async
// On validation error, returns HTTP 400:
// {
// "code": "VALIDATION_FAILED",
// "message": "Invalid input",
// "details": {
// "fields": {
// "email": "must be a valid email",
// "age": "must be 18 or older"
// }
// },
// "trace_id": "abc-123",
// "retryable": false
// }
Table of Contents
- Why error-envelope
- Installation
- Quick Start
- Examples
- API Reference - Complete API documentation
- Error Codes - All 18 error codes with descriptions
Why error-envelope
APIs need a formal contract for errors. Without one, clients can't predict error structure:
String field, no structure.
Different field names, ad-hoc.
Array structure, incompatible.
Every endpoint becomes a special case. error-envelope establishes a predictable contract: same structure, same fields, every time.
Installation
[]
= "0.3"
With optional features:
[]
= { = "0.3", = ["axum-support", "anyhow-support"] }
You can enable either or both features depending on your use case.
π Full API documentation: docs.rs/error-envelope
Crate Features
| Feature | Description |
|---|---|
default |
Core error envelope with no framework dependencies |
axum-support |
Adds IntoResponse implementation for Axum framework integration |
anyhow-support |
Enables From<anyhow::Error> conversion for seamless interop with anyhow |
Quick Start
use Error;
use Duration;
// Create errors with builder pattern:
let err = rate_limited
.with_trace_id
.with_retry_after;
That's it. See the hero example above for Axum integration and validation patterns.
Framework Integration
Axum
With the axum-support feature, Error implements IntoResponse:
use ;
use Error;
async
// Error automatically converts to HTTP response with:
// - Correct status code
// - JSON body with error envelope
// - X-Request-ID header (if trace_id set)
// - Retry-After header (if retry_after set)
API Reference
Common constructors for typical scenarios:
use Error;
// Most common
internal; // 500
not_found; // 404
unauthorized; // 401
forbidden; // 403
// Validation
bad_request; // 400
use validation;
let err = validation; // 400 with field details
// Infrastructure
rate_limited; // 429
timeout; // 504
Builder pattern:
let err = rate_limited
.with_details
.with_trace_id
.with_retry_after;
π Full API documentation: API.md - Complete constructor reference, formatted helpers, advanced patterns
Error Codes
18 standard codes as a type-safe enum. Most common:
| Code | HTTP Status | Use Case |
|---|---|---|
Internal |
500 | Unexpected server errors |
NotFound |
404 | Resource doesn't exist |
Unauthorized |
401 | Missing/invalid auth |
ValidationFailed |
400 | Invalid input data |
Timeout |
504 | Gateway timeout (retryable) |
π Complete reference: ERROR_CODES.md - All 18 codes with detailed descriptions, use cases, and retryable behavior
Design Principles
Minimal, framework-agnostic core (~500 lines); integrations behind feature flags. See ARCHITECTURE.md for design rationale.
Examples
Complete working examples in the examples/ directory:
domain_errors.rs- Map thiserror domain errors to HTTP errors (From pattern)validation.rs- Field-level validation with structured error detailsrate_limiting.rs- Rate limiting with retry-after hintstracing.rs- Trace ID propagation through middlewareaxum_server.rs- Complete Axum server with all patterns
Run any example:
Testing
License
MIT