waddling-errors 0.5.0

Ultra-minimal error code standard for the Waddling ecosystem
Documentation

waddling-errors 🦆

Type-safe diagnostic code system with structured error codes

Crates.io Documentation License


Overview

waddling-errors provides structured diagnostic codes with a consistent 4-part format:

SEVERITY.COMPONENT.PRIMARY.SEQUENCE
E.AUTH.TOKEN.001    // Error in Auth component, Token category, sequence 001
W.PARSER.SYNTAX.003 // Warning in Parser component, Syntax category, sequence 003
S.BUILD.DONE.999    // Success in Build component, Done category, sequence 999

Key Features

  • ✅ Type-safe - Define your own component/primary enums with compile-time checking
  • ✅ Zero dependencies by default - Modular features (doc-gen, hash, serde)
  • ✅ Semantic methods - is_blocking(), is_positive(), priority() for intelligent error handling
  • ✅ Documentation generation - Auto-generate JSON/HTML/Catalog docs with role-based filtering
  • ✅ Hash codes - Optional 5-character base62 hashes for compact logging
  • ✅ Network efficiency - Catalog renderer for 80% smaller payloads (IoT/mobile)
  • ✅ no_std compatible - Works in embedded and WASM environments

Installation

[dependencies]

# Default (no_std + alloc compatible, includes macros)

waddling-errors = "0.5"



# With documentation generation (requires std)

waddling-errors = { version = "0.5", features = ["std", "doc-gen", "hash", "serde"] }



# Pure no_std (no allocator)

waddling-errors = { version = "0.5", default-features = false }



# For procedural macros separately

waddling-errors-macros = "0.5"

Default features: ["macros"] - Works in no_std + alloc environments.

See docs/FEATURE_FLAGS.md for detailed feature information.


Quick Start

Manual Approach (Core Library)

use waddling_errors::prelude::*;

// 1. Define your error structure
#[derive(Debug, Copy, Clone)]
enum Component { Auth, Parser, Database }

impl ComponentId for Component {
    fn as_str(&self) -> &'static str {
        match self {
            Component::Auth => "AUTH",
            Component::Parser => "PARSER",
            Component::Database => "DB",
        }
    }
}

#[derive(Debug, Copy, Clone)]
enum Primary { Token, Syntax, Connection }

impl PrimaryId for Primary {
    fn as_str(&self) -> &'static str {
        match self {
            Primary::Token => "TOKEN",
            Primary::Syntax => "SYNTAX",
            Primary::Connection => "CONN",
        }
    }
}

// 2. Create error codes
const ERR_TOKEN_MISSING: Code<Component, Primary> = 
    Code::error(Component::Auth, Primary::Token, 1);

// 3. Use them
fn authenticate(token: Option<&str>) -> Result<(), Code<Component, Primary>> {
    token.ok_or(ERR_TOKEN_MISSING)?;
    Ok(())
}

fn main() {
    println!("{}", ERR_TOKEN_MISSING.code());  // "E.AUTH.TOKEN.001"
    println!("Priority: {}", ERR_TOKEN_MISSING.severity().priority());  // 8
    println!("Blocking? {}", ERR_TOKEN_MISSING.severity().is_blocking());  // true
}

Macro Approach (Recommended)

For less boilerplate, use waddling-errors-macros:

use waddling_errors_macros::{component, primary, diag};

component! { Auth { value: "AUTH", docs: "Authentication" } }
primary! { Token { value: "TOKEN", docs: "Token errors" } }

diag! {
    E.AUTH.TOKEN.EXPIRED: {
        message: "JWT token expired at {timestamp}",
        fields: [timestamp],
        'CR 'Pub description: "Your session has expired. Please log in again.",
    }
}

let error = E_AUTH_TOKEN_EXPIRED;

See waddling-errors-macros for macro documentation.


Severity Levels

Nine severity levels with semantic methods:

Severity Code Priority Blocking Use Case
Error E 8 Yes Invalid input, logic errors
Blocked B 7 Yes Deadlock, I/O wait, network down
Critical C 6 No Data corruption, resource exhaustion
Warning W 5 No Deprecated API, edge cases
Help H 4 No Helpful suggestions, tips
Success S 3 No Operation succeeded
Completed K 2 No Task/phase finished
Info I 1 No Events, milestones, status
Trace T 0 No Execution traces, probes, timing
let severity = Severity::Error;

severity.is_blocking();   // true - stops execution
severity.is_negative();   // true - indicates failure
severity.is_positive();   // false
severity.priority();      // 8 (0-8 scale)

Optional emoji/ANSI color support available with features. See FEATURE_FLAGS.md.


Documentation Generation

Generate searchable HTML and JSON documentation with role-based filtering:

use waddling_errors::doc_generator::{DocRegistry, JsonRenderer, HtmlRenderer};
use waddling_errors::Role;

let mut registry = DocRegistry::new("My API", "1.0.0");

// Register components and errors
registry.register_component("AUTH", Some("Authentication system"), &[], &["security"])?;
registry.register_code_extended(
    &ERR_TOKEN_MISSING,
    "JWT token missing from Authorization header",
    &["Include Authorization: Bearer <token> header"],
    &["auth", "security"],
    Some(Role::Public),
    &[], None, &[],
)?;

// Generate documentation for all roles
registry.render_all_roles(
    vec![Box::new(JsonRenderer), Box::new(HtmlRenderer::new())],
    "target/docs"
)?;

// Generates:
//   myapp-pub.html, myapp-pub.json   - Public documentation
//   myapp-dev.html, myapp-dev.json   - Developer documentation
//   myapp-int.html, myapp-int.json   - Internal documentation

Documentation Roles:

  • Role::Public - End-user facing errors (sanitized, safe)
  • Role::Developer - For contributors (debugging context)
  • Role::Internal - Full team visibility (sensitive details)

See docs/DOC_GENERATION_GUIDE.md for complete guide.


Network Efficiency (Catalog Renderer)

Generate compact catalogs for efficient error transmission:

use waddling_errors::doc_generator::{CatalogRenderer, CatalogFormat};

// Generate hash-to-error catalog
let catalog = CatalogRenderer::new(CatalogFormat::Compact);
registry.render(vec![Box::new(catalog)], "target/catalog")?;

// Server sends: {"h":"jGKFp","f":{"temp":"45.2"}}  (40 bytes)
// Client expands: "Temperature 45.2°C exceeds threshold"

Benefits:

  • 80% smaller network payloads for IoT/mobile
  • Multi-language support (same hash, different catalogs)
  • Offline-first apps (cache catalog locally)

See docs/CATALOG_GUIDE.md for complete guide.


no_std Support

The library is no_std compatible by default and works in embedded/WASM environments:

Default (no_std + alloc):

[dependencies]

waddling-errors = "0.5"  # Works with allocator

Pure no_std (no allocator):

[dependencies]

waddling-errors = { version = "0.5", default-features = false }

Example:

#![no_std]
extern crate alloc;

use waddling_errors::prelude::*;

// Works without std!
const ERR: Code<Component, Primary> = Code::error(Component::Auth, Primary::Token, 1);

For documentation generation (requires std):

waddling-errors = { version = "0.5", features = ["std", "doc-gen", "metadata"] }


Hash Codes

Enable 5-character base62 hashes for compact logging:

waddling-errors = { version = "0.5", features = ["hash"] }

const ERR: Code<Component, Primary> = Code::error(Component::Auth, Primary::Token, 1);

println!("{} → #{}", ERR.code(), ERR.hash());
// E.AUTH.TOKEN.001 → #jGKFp

// Use in logs for quick searches
log::error!("#{} Authentication failed", ERR.hash());

Sequence Conventions

Semantic sequence numbers provide consistency across projects:

Sequence Meaning Example
001 MISSING Required item not provided
003 INVALID Format/validation failed
007 DUPLICATE Rate limit or duplicate entry
008 DENIED Permission/access denied
021 NOTFOUND Resource not found
025 CORRUPTED Data corruption detected
999 COMPLETE Full completion

See docs/SEQUENCE-CONVENTIONS.md for the complete list.


Examples

Basic usage:

cargo run --example trait_based_enums

With documentation metadata:

cargo run --example trait_based_documented

Production pattern (6 components, 31 errors, role-based docs):

cargo run --example complete_system --features "doc-gen,hash"

HTML customization:

cargo run --example html_customization_demo --features "doc-gen,metadata"

no_std/WASM:

# Pure no_std

cargo build --example wasm_minimal --target wasm32-unknown-unknown --no-default-features


# With no_std example

cargo run --example no_std_example --no-default-features

See examples/ directory for all examples.


Documentation

User Guides

API Reference

Related Crates


License

Dual-licensed under MIT or Apache-2.0. See LICENSE-MIT and LICENSE-APACHE.