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, AppResult, ForgeError};
64
65// Historical re-export. `Result` shadows `std::result::Result` in
66// glob imports; deprecated in favour of `AppResult`. Kept for
67// source compatibility through the `1.x` line.
68#[allow(deprecated)]
69pub use crate::error::Result;
70
71// Re-export context module
72pub use crate::context::{ContextError, ResultExt};
73
74// Re-export registry module
75pub use crate::registry::{
76    register_error_code, CodedError, ErrorCodeInfo, ErrorRegistry, WithErrorCode,
77};
78
79// Re-export collector module
80pub use crate::collector::{CollectError, ErrorCollector};
81
82// Re-export logging module
83pub use crate::logging::{log_error, logger, register_logger, ErrorLogger};
84
85// Re-export async module (when enabled)
86#[cfg(feature = "async")]
87pub use crate::async_error::{AsyncForgeError, AsyncResult};
88
89// Re-export hook types from `macros` — explicitly named so the
90// public surface stays under our control. `define_errors!` and
91// `group!` are re-exported automatically because they are
92// `#[macro_export]`'d.
93#[allow(deprecated)]
94pub use crate::macros::{
95    register_error_hook, try_register_error_hook, ErrorContext, ErrorLevel, ErrorSource,
96};
97
98// Optional re-export of the proc macro
99#[cfg(feature = "derive")]
100pub use error_forge_derive::*;
101
102/// Internal re-exports for use by macros expanded in user crates.
103///
104/// This module is not part of the public API. Items here may
105/// change at any time without notice. They are exposed only so
106/// that `define_errors!` (and other macros that expand into user
107/// code) can reference dependencies through `$crate::__private::*`
108/// without forcing every user to add those crates to their own
109/// `Cargo.toml`.
110#[doc(hidden)]
111pub mod __private {
112    pub use pastey;
113}
114
115// Extension methods are implemented in error.rs
116
117#[cfg(test)]
118mod tests {
119    use crate::ForgeError;
120
121    #[test]
122    fn test_error_display() {
123        let err = crate::error::AppError::config("Test error");
124        assert!(err.to_string().contains("Test error"));
125    }
126
127    #[test]
128    fn test_error_kind() {
129        let err = crate::error::AppError::config("Test error");
130        assert_eq!(err.kind(), "Config");
131    }
132}