Skip to main content

error_forge/
lib.rs

1//! # Error Forge
2//!
3//! Error Forge is a pragmatic Rust error-handling crate for applications that need
4//! structured metadata, readable output, and operational hooks without forcing a
5//! single application architecture.
6//!
7//! It provides:
8//!
9//! - [`ForgeError`] for stable error metadata
10//! - [`AppError`] for immediate use in small and medium projects
11//! - [`define_errors!`] for declarative custom enums
12//! - [`group!`] for coarse-grained composition
13//! - optional derive support with `#[derive(ModError)]`
14//! - context wrapping, error codes, collectors, logging hooks, and console formatting
15//! - synchronous retry and circuit-breaker helpers in [`recovery`]
16//!
17//! ## Quick Start
18//!
19//! ```
20//! use error_forge::{define_errors, ForgeError};
21//!
22//! define_errors! {
23//!     pub enum ServiceError {
24//!         #[error(display = "Configuration error: {message}", message)]
25//!         #[kind(Config, status = 500)]
26//!         Config { message: String },
27//!
28//!         #[error(display = "Request to {endpoint} failed", endpoint)]
29//!         #[kind(Network, retryable = true, status = 503)]
30//!         Network { endpoint: String },
31//!     }
32//! }
33//!
34//! let error = ServiceError::config("Missing DATABASE_URL".to_string());
35//! assert_eq!(error.kind(), "Config");
36//! ```
37//!
38//! ## Built-in Formatting
39//!
40//! ```
41//! use error_forge::{console_theme::print_error, AppError};
42//!
43//! let error = AppError::config("Database connection failed");
44//! print_error(&error);
45//! ```
46pub mod collector;
47pub mod console_theme;
48pub mod context;
49pub mod error;
50pub mod group_macro;
51pub mod logging;
52pub mod macros;
53pub mod recovery;
54pub mod registry;
55
56#[cfg(feature = "async")]
57pub mod async_error;
58#[cfg(feature = "async")]
59pub mod async_error_impl;
60
61// Re-export core types and traits
62pub use crate::console_theme::{install_panic_hook, print_error, ConsoleTheme};
63pub use crate::error::{AppError, ForgeError, Result};
64
65// Re-export context module
66pub use crate::context::{ContextError, ResultExt};
67
68// Re-export registry module
69pub use crate::registry::{
70    register_error_code, CodedError, ErrorCodeInfo, ErrorRegistry, WithErrorCode,
71};
72
73// Re-export collector module
74pub use crate::collector::{CollectError, ErrorCollector};
75
76// Re-export logging module
77pub use crate::logging::{log_error, logger, register_logger, ErrorLogger};
78
79// Re-export async module (when enabled)
80#[cfg(feature = "async")]
81pub use crate::async_error::{AsyncForgeError, AsyncResult};
82
83// Re-export macros for convenient use
84#[allow(unused_imports)]
85pub use crate::macros::*;
86
87// Optional re-export of the proc macro
88#[cfg(feature = "derive")]
89pub use error_forge_derive::*;
90
91/// Internal re-exports for use by macros expanded in user crates.
92///
93/// This module is not part of the public API. Items here may
94/// change at any time without notice. They are exposed only so
95/// that `define_errors!` (and other macros that expand into user
96/// code) can reference dependencies through `$crate::__private::*`
97/// without forcing every user to add those crates to their own
98/// `Cargo.toml`.
99#[doc(hidden)]
100pub mod __private {
101    pub use pastey;
102}
103
104// Extension methods are implemented in error.rs
105
106#[cfg(test)]
107mod tests {
108    use crate::ForgeError;
109
110    #[test]
111    fn test_error_display() {
112        let err = crate::error::AppError::config("Test error");
113        assert!(err.to_string().contains("Test error"));
114    }
115
116    #[test]
117    fn test_error_kind() {
118        let err = crate::error::AppError::config("Test error");
119        assert_eq!(err.kind(), "Config");
120    }
121}