Skip to content

Commit c1d0011

Browse files
committed
Update 0.6.0
1 parent a9954d4 commit c1d0011

8 files changed

Lines changed: 832 additions & 48 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/dev
33
DIRECTIVE.md
44
DIRECTIVES.md
5+
PLANNING.md
56

67
# Rust/Cargo Build Artifacts
78
/target/

API.md

Lines changed: 0 additions & 32 deletions
This file was deleted.

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "error-forge"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
edition = "2021"
55
readme = "README.md"
66
license = "Apache-2.0"
@@ -30,13 +30,11 @@ repository = "https://github.com/jamesgober/error-forge"
3030
homepage = "https://github.com/jamesgober/error-forge"
3131

3232

33-
3433
[dependencies]
3534
thiserror = "1.0"
3635
paste = "1.0"
3736
error-forge-derive = {version = "0.1.0", path = "./error-forge-derive", optional = true }
3837

39-
4038
[features]
4139
default = []
4240
serde = []

README.md

Lines changed: 186 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,189 @@
1212
<span>&nbsp;</span>
1313
<a href="https://github.com/jamesgober/error-forge/actions"><img alt="GitHub CI" src="https://github.com/jamesgober/error-forge/actions/workflows/ci.yml/badge.svg"></a>
1414
</div>
15-
<br>
15+
<br>
16+
17+
# Error Forge
18+
19+
Error Forge is a comprehensive, zero-dependency error management framework for Rust applications. It simplifies error handling through expressive macros, automatic trait implementations, and extensible error hooks for seamless integration with external logging systems.
20+
21+
## Features
22+
23+
- **Rich Error Types**: Define expressive error types with minimal boilerplate
24+
- **ForgeError Trait**: Unified interface for all error types with contextual metadata
25+
- **Declarative Macros**: Generate complete error enums with the `define_errors!` macro
26+
- **Error Composition**: Combine errors from multiple modules with the `group!` macro
27+
- **Derive Macros**: Quickly implement errors with `#[derive(ModError)]`
28+
- **Console Formatting**: ANSI color formatting for terminal output with `ConsoleTheme`
29+
- **Error Hooks**: Register callbacks for errors with severity level support
30+
- **Zero External Dependencies**: Completely standalone with no third-party dependencies
31+
32+
## Installation
33+
34+
Add the following to your `Cargo.toml` file:
35+
36+
```toml
37+
[dependencies]
38+
error-forge = "0.6.0"
39+
```
40+
41+
## Usage
42+
43+
### Basic Error Definition
44+
45+
```rust
46+
use error_forge::define_errors;
47+
48+
define_errors! {
49+
pub enum DatabaseError {
50+
#[error(display = "Database connection failed: {}", message)]
51+
ConnectionFailed { message: String },
52+
53+
#[error(display = "Query execution failed: {}", message)]
54+
QueryFailed { message: String, query: String },
55+
56+
#[error(display = "Record not found with ID: {}", id)]
57+
RecordNotFound { id: String },
58+
}
59+
}
60+
61+
// The macro automatically implements constructors and the ForgeError trait
62+
fn main() -> Result<(), Box<dyn std::error::Error>> {
63+
// Create an error using the generated constructor
64+
let error = DatabaseError::connection_failed("Timeout after 30 seconds");
65+
66+
// Use ForgeError methods
67+
println!("Error kind: {}", error.kind());
68+
println!("Caption: {}", error.caption());
69+
println!("Status code: {}", error.status_code());
70+
71+
Err(Box::new(error))
72+
}
73+
```
74+
75+
### Error Composition with the `group!` Macro
76+
77+
```rust
78+
use error_forge::{define_errors, group};
79+
80+
define_errors! {
81+
pub enum ApiError {
82+
#[error(display = "Invalid API key")]
83+
InvalidApiKey,
84+
85+
#[error(display = "Rate limit exceeded")]
86+
RateLimitExceeded,
87+
}
88+
}
89+
90+
define_errors! {
91+
pub enum ValidationError {
92+
#[error(display = "Required field {} is missing", field)]
93+
MissingField { field: String },
94+
95+
#[error(display = "Field {} has invalid format", field)]
96+
InvalidFormat { field: String },
97+
}
98+
}
99+
100+
// Combine errors from different modules into a single error type
101+
group! {
102+
pub enum AppError {
103+
Api(ApiError),
104+
Validation(ValidationError),
105+
// Add more error types as needed
106+
}
107+
}
108+
109+
fn validate_request() -> Result<(), AppError> {
110+
// Create a ValidationError
111+
let error = ValidationError::missing_field("username");
112+
113+
// The error will be automatically converted to AppError
114+
Err(error.into())
115+
}
116+
```
117+
118+
### Using Derive Macro
119+
120+
```rust
121+
use error_forge::ModError;
122+
123+
#[derive(Debug, ModError)]
124+
#[module_error(kind = "AuthError")]
125+
pub enum AuthError {
126+
#[error(display = "Invalid credentials")]
127+
InvalidCredentials,
128+
129+
#[error(display = "Account locked: {}", reason)]
130+
AccountLocked { reason: String },
131+
132+
#[error(display = "Session expired")]
133+
#[http_status(401)]
134+
SessionExpired,
135+
}
136+
137+
fn login() -> Result<(), AuthError> {
138+
Err(AuthError::InvalidCredentials)
139+
}
140+
```
141+
142+
### Error Hooks for Logging Integration
143+
144+
```rust
145+
use error_forge::{AppError, macros::{register_error_hook, ErrorLevel, ErrorContext}};
146+
147+
fn main() {
148+
// Register a hook for centralized error handling
149+
register_error_hook(|ctx| {
150+
match ctx.level {
151+
ErrorLevel::Info => println!("INFO: {} [{}]", ctx.caption, ctx.kind),
152+
ErrorLevel::Warning => println!("WARN: {} [{}]", ctx.caption, ctx.kind),
153+
ErrorLevel::Error => println!("ERROR: {} [{}]", ctx.caption, ctx.kind),
154+
ErrorLevel::Critical => {
155+
println!("CRITICAL: {} [{}]", ctx.caption, ctx.kind);
156+
157+
// Send notifications for critical errors
158+
if ctx.is_fatal {
159+
send_notification("Critical error occurred", ctx.caption);
160+
}
161+
}
162+
}
163+
});
164+
165+
// This will trigger the hook
166+
let _error = AppError::config("Configuration file not found");
167+
}
168+
169+
fn send_notification(level: &str, message: &str) {
170+
// Send notifications via your preferred channel
171+
println!("Notification sent: {} - {}", level, message);
172+
}
173+
```
174+
175+
### Console Formatting
176+
177+
```rust
178+
use error_forge::{AppError, ConsoleTheme};
179+
180+
fn main() {
181+
// Create an error
182+
let error = AppError::config("Database configuration missing");
183+
184+
// Set up console theme
185+
let theme = ConsoleTheme::new();
186+
187+
// Print formatted error
188+
println!("{}", theme.format_error(&error));
189+
190+
// Install panic hook for consistent formatting
191+
theme.install_panic_hook();
192+
193+
// This panic will be formatted consistently with other errors
194+
panic!("Something went wrong!");
195+
}
196+
```
197+
198+
## Advanced Usage
199+
200+
For more detailed documentation and advanced usage examples, refer to the [API Documentation](docs/API.md).

0 commit comments

Comments
 (0)