waddling-errors 🦆
Ultra-minimal diagnostic code system
Overview
waddling-errors provides a super ergonomic diagnostic code system with consistent error code format generation.
Key Features
- ✅ Tiny - Only ~500 bytes without hashing, ~30KB with SHA256 (optional)
- ✅ Zero dependencies by default - No forced dependencies
- ✅ Flexible - Enum-based error codes with optional SHA256 hashing
- ✅ Consistent - Same error format for diagnostic tooling integration
- ✅
no_stdcompatible - Works in embedded and WASM environments - ✅ Const-friendly - Error codes can be defined as constants
Why This Exists
Projects need consistent error code formats for diagnostic tooling integration.
Standard Format
4-Part Format - consistent diagnostic codes:
SEVERITY.COMPONENT.PRIMARY.SEQUENCE → E.CRYPTO.SALT.001
Where SEVERITY can be:
| Severity | Code | Use Case |
|---|---|---|
| Error | E |
Invalid input, logic errors |
| Warning | W |
Deprecated API, edge cases |
| Critical | C |
Data corruption, security breach |
| Blocked | B |
Deadlock, I/O wait, network down |
| Success | S |
Operation succeeded ✅ |
| Completed | K |
Task/phase finished ✅ |
| Info | I |
Events, milestones, status |
| Trace | T |
Execution traces, probes, timing |
Solution: waddling-errors provides a single, minimal, flexible implementation.
Installation
Add to your Cargo.toml:
[]
# Minimal (no hashing) - ultra lightweight
= { = "0.1", = false }
# With ahash hashing - fast deterministic hashing
= { = "0.1", = ["hash"] }
Quick Start
use *;
// Ultra-clean error definitions
const ERR_SALT: Code = error;
const WARN_DEPRECATED: Code = warning;
const SUCCESS_BUILD: Code = success;
Usage Patterns
waddling-errors provides multiple API styles - choose what fits your project:
1. Convenience Functions (Recommended)
The cleanest, most ergonomic approach:
use *;
// All 8 severity levels
const ERR: Code = error;
const WARN: Code = warning;
const CRIT: Code = critical;
const BLOCK: Code = blocked;
const SUCCESS: Code = success;
const COMPLETE: Code = completed;
const INFO: Code = info;
const TRACE: Code = trace;
2. Method Style
Object-oriented approach:
use Code;
const ERR: Code = error;
const WARN: Code = warning;
3. Explicit Severity
Full control when needed:
use ;
const ERR: Code = new;
Standalone Usage (No Dependencies)
Return diagnostic codes directly:
use *;
const ERR_INVALID_SALT: Code = error;
// Or wrap in your own error type
See examples/standalone.rs for a complete example with no external dependencies.
Error Registry Pattern (Recommended)
For larger projects, create a central error registry:
// errors.rs - Your project's error registry
// Use across your project
use SALT_MISSING;
Benefits:
- ✅ Centralized error definitions
- ✅ Easy to document and maintain
- ✅ Prevents duplicate sequence numbers
- ✅ IDE autocomplete for all error codes
Optional Integration: thiserror
If you're already using thiserror, waddling-errors integrates seamlessly:
use *;
use Error; // Optional - not required!
// Define codes in your error registry (errors.rs)
const ERR_INVALID_SALT: Code = error;
const ERR_MAC_FAILED: Code = error;
// Wrap with thiserror in your error type
// Usage in your functions
// Error output:
// [E.CRYPTO.SALT.001] Invalid salt length: expected 32 bytes, got 16 bytes
Note: thiserror is completely optional. waddling-errors works standalone or with any error handling library (anyhow, eyre, custom types, etc.).
See examples/integration_thiserror.rs for a complete integration example.
Advanced Usage (With Hashing)
Enable fast deterministic hashing with the hash feature (uses ahash with "Waddling" salt):
use *;
const ERR: Code = error;
println!; // E.CRYPTO.SALT.001
println!; // 5-char base62 hash (alphanumeric, safe for logging)
Hash features:
- ✅ Base62 encoding (0-9, A-Z, a-z only)
- ✅ Safe for all logging systems (no special characters)
- ✅ 916M combinations (~14,000x better than 4-char hex)
- ✅ Deterministic and fast
Severity Levels
waddling-errors provides 8 severity levels for comprehensive diagnostic coverage:
| Severity | Code | Description |
|---|---|---|
| Error | E |
Operation failed |
| Warning | W |
Potential issue or caveat |
| Critical | C |
Severe issue requiring attention |
| Blocked | B |
Execution blocked/waiting |
| Success | S |
Operation succeeded |
| Completed | K |
Task or phase completed |
| Info | I |
Events, milestones, status |
| Trace | T |
Execution traces, probes, timing |
Severity Helpers
use ;
const ERR: Code = error;
// Get severity level (0-7, higher = more severe)
let level = ERR.severity.level; // 7 for Error
// Check if positive outcome (Success/Completed)
let is_good = ERR.severity.is_positive; // false
Example: Running the Severity Matrix Demo
This shows all severity levels with real-world use cases.
Sequence Conventions 🔢
To maximize consistency, certain sequence numbers have reserved semantic meanings.
Quick Reference
| Sequence | Meaning | Example |
|---|---|---|
| 001 | MISSING | E.CRYPTO.SALT.001 - Salt missing |
| 002 | MISMATCH | E.CRYPTO.LENGTH.002 - Length mismatch |
| 003 | INVALID | E.PATTERN.REGEX.003 - Invalid format |
| 021 | NOTFOUND | E.DATA.KEY.021 - Resource not found |
| 025 | CORRUPTED | C.CRYPTO.MAC.025 - Data corrupted |
| 031-897 | (project-specific) | Domain logic errors |
| 999 | COMPLETE | S.BUILD.DONE.999 - Full completion |
Benefits:
- ✅ Instant Recognition:
.001always means "missing" across projects - ✅ Cross-Project Learning: Consistent patterns improve understanding
- ✅ Searchability: Search
.001finds all "missing" errors
Example Usage
use ;
// Following conventions (recommended)
const ERR_MISSING_SALT: ErrorCode =
new; // .001 = MISSING ✅
const ERR_LENGTH_MISMATCH: ErrorCode =
new; // .002 = MISMATCH ✅
// Domain-specific (project-specific range)
const ERR_HMAC_COMPUTE: ErrorCode =
new; // 031-897 range ✅
Convention Status
These are SHOULD guidelines (RFC 2119), not requirements. Projects are encouraged but not forced to follow them.
Full documentation: docs/SEQUENCE-CONVENTIONS.md
Enforcement strategies: docs/ENFORCEMENT.md
API
ErrorCode Struct
Methods
// Create a new error code (const fn - can be used in constants!)
pub const ;
// Get the full error code string (e.g., "CRYPTO.SALT.001")
;
// Get component (e.g., "CRYPTO")
pub const ;
// Get primary category (e.g., "SALT")
pub const ;
// Get sequence number (e.g., 1)
pub const ;
// Get 4-character SHA256 hash (requires "hash" feature)
;
Features
Default Features
By default, no features are enabled for minimal binary size.
[]
= { = "0.1", = false }
Size: ~500 bytes
Optional Features
hash - SHA256-based error code hashing
Adds a 4-character hash based on the error code for stable error identification.
[]
= { = "0.1", = ["hash"] }
Size: ~30KB (includes SHA256 implementation from sha2 crate)
Use when:
- Building diagnostic/compiler tools
- Need stable error identifiers for documentation
- Want to link errors to docs pages
Examples
Standalone (No Dependencies)
See examples/standalone.rs for pure waddling-errors usage with zero external dependencies:
Shows:
- ✅ Direct ErrorCode returns
- ✅ Custom DIY error types
- ✅ No thiserror/anyhow needed
- ✅ Works in no_std environments
Optional: Integration with thiserror
See examples/integration_thiserror.rs for integration with thiserror (if you're already using it):
Shows:
- ✅ Wrapping error codes in thiserror enums
- ✅ Professional error messages
- ✅ Note: thiserror is completely optional!
Severity Matrix Demo
See examples/severity_matrix.rs for a visual demonstration of all severity levels:
Shows all 8 severity levels with real-world use cases and the blocking/actionable matrix.
Error Handling Approaches
waddling-errors supports multiple approaches - choose what fits your project:
| Approach | Dependencies | Complexity | Use Case |
|---|---|---|---|
| Direct ErrorCode | None | Minimal | Simple libraries, no_std |
| DIY Error Type | None | Low | Custom error handling |
| With thiserror | thiserror | Medium | Professional errors |
| With anyhow | anyhow | Low | Applications |
All approaches work! Choose based on your needs, not waddling-errors requirements.
Format Convention
Consistent error code format for better diagnostics:
4-Part Format
SEVERITY.COMPONENT.PRIMARY.SEQUENCE
E.CRYPTO.SALT.001
Examples:
E.CRYPTO.SALT.001- Invalid salt lengthW.API.DEPR.001- Deprecated API usageE.parser.SYNTAX.001- Syntax errorS.BUILD.DONE.001- Build successful
This consistency allows:
- ✅ Instantly recognize error types
- ✅ Search documentation effectively
- ✅ Track error patterns with analytics
- ✅ Reference stable error codes in issues/docs
Binary Size Comparison
| Configuration | Binary Size | Use Case |
|---|---|---|
| No waddling-errors | 0 bytes | No error codes |
| waddling-errors (default) | ~500 bytes | Minimal libraries |
| waddling-errors (hash) | ~30KB | Diagnostic tools |
| DIY implementation | ~500 bytes | But duplicated across projects |
Key insight: The ~500 byte cost is amortized across projects since they share the same crate. SHA256 is deduplicated by Cargo if multiple projects enable the hash feature.
Roadmap
- v0.1.0 - Initial release with
ErrorCodestruct - v0.1.1 - Add error code registry (optional feature)
- v0.2.0 - Add error code documentation generator
- v0.3.0 - Add error analytics helpers
Contributing
Contributions welcome! This is a minimal, stable crate, so new features should:
- Be opt-in via feature flags
- Not increase default binary size
- Maintain
no_stdcompatibility
Please open an issue before submitting large PRs.
License
Dual-licensed under MIT or Apache-2.0.