1 stable release
new 1.2.6 | May 25, 2025 |
---|---|
0.1.0 |
|
#311 in Rust patterns
635KB
13K
SLoC
Decrust
A comprehensive error handling framework for Rust applications that provides structured error types, rich context, intelligent autocorrection suggestions, and resilience patterns.
Features
🎯 Core Error Handling
- Unified Error Type: A comprehensive
DecrustError
enum covering 16+ error scenarios - Rich Error Context: Detailed error information with source location, metadata, and recovery suggestions
- Backtrace Support: Environment-aware backtrace capture with zero external dependencies
- Error Categorization: Automatic categorization of errors for better handling and reporting
🔧 Intelligent Autocorrection Framework
- 39 Error Types Supported: Automatic, interactive, and manual guidance for common programming errors
- AST-Aware Fixes: Context-aware code generation and syntax tree manipulation
- Template-Based Generation: Extensible fix templates for consistent code generation
- Parameter Extraction: Regex and diagnostic-based parameter extraction from error messages
🛡️ Resilience Patterns
- Circuit Breaker: Production-ready circuit breaker implementation with metrics
- Fault Tolerance: Configurable failure thresholds and recovery strategies
- Observer Pattern: Extensible event system for monitoring circuit breaker state
- Async Support: Full async/await support with Tokio integration
📊 Advanced Reporting
- Multiple Formats: Plain text, JSON, Markdown, and HTML output
- Syntax Highlighting: AST-aware code snippet formatting
- Structured Output: Machine-readable error reports for tooling integration
- Configurable Verbosity: Fine-grained control over report content
Quick Start
Add Decrust to your Cargo.toml
:
[dependencies]
decrust = "0.1.0"
Basic Error Handling
use decrust::{DecrustError, Result, OptionalError};
use decrust::backtrace::DecrustBacktrace;
use std::path::PathBuf;
fn read_config_file(path: &str) -> Result<String> {
// Simulate a file not found error
Err(DecrustError::Io {
source: std::io::Error::new(std::io::ErrorKind::NotFound, "File not found"),
path: Some(PathBuf::from(path)),
operation: "read_file".to_string(),
backtrace: DecrustBacktrace::capture(),
})
}
fn main() -> Result<()> {
match read_config_file("config.toml") {
Ok(content) => println!("Config: {}", content),
Err(error) => {
eprintln!("Error: {}", error);
eprintln!("Category: {:?}", error.category());
// Check for backtrace
if let Some(backtrace) = error.backtrace() {
eprintln!("Backtrace: {:?}", backtrace.status());
}
}
}
Ok(())
}
Error Reporting
use decrust::reporter::{ErrorReporter, ErrorReportConfig};
use decrust::types::ErrorReportFormat;
let error = DecrustError::Validation {
field: "email".to_string(),
message: "Invalid email format: missing '@' symbol".to_string(),
backtrace: DecrustBacktrace::capture(),
};
let reporter = ErrorReporter::new();
// Plain text report
let plain_config = ErrorReportConfig {
format: ErrorReportFormat::Plain,
..Default::default()
};
println!("{}", reporter.report_to_string(&error, &plain_config));
// JSON report
let json_config = ErrorReportConfig {
format: ErrorReportFormat::Json,
pretty_print_json: true,
..Default::default()
};
println!("{}", reporter.report_to_string(&error, &json_config));
Circuit Breaker Pattern
use decrust::circuit_breaker::{CircuitBreaker, CircuitBreakerConfig};
use std::time::Duration;
let config = CircuitBreakerConfig {
failure_threshold: 5,
reset_timeout: Duration::from_secs(30),
operation_timeout: Some(Duration::from_secs(5)),
..Default::default()
};
let circuit_breaker = CircuitBreaker::new("external_service", config);
// Execute operation through circuit breaker
let result = circuit_breaker.execute(|| {
// Your potentially failing operation
external_api_call()
});
match result {
Ok(data) => println!("Success: {:?}", data),
Err(DecrustError::CircuitBreakerOpen { name, retry_after, .. }) => {
println!("Circuit breaker '{}' is open", name);
if let Some(retry) = retry_after {
println!("Retry after: {:?}", retry);
}
},
Err(other) => println!("Other error: {}", other),
}
Autocorrection System
use decrust::decrust::{Decrust, RegexParameterExtractor, DiagnosticParameterExtractor};
let mut decrust = Decrust::new();
// Register parameter extractors
decrust.register_parameter_extractor(Box::new(RegexParameterExtractor::new()));
decrust.register_parameter_extractor(Box::new(DiagnosticParameterExtractor::new()));
// Get autocorrection suggestions
if let Some(suggestion) = decrust.get_autocorrection_suggestion(&error) {
println!("Fix suggestion: {}", suggestion.description);
println!("Confidence: {:.1}%", suggestion.confidence * 100.0);
println!("Fix type: {:?}", suggestion.fix_type);
}
Error Types
Decrust provides 16 comprehensive error variants:
Error Type | Description | Use Case |
---|---|---|
Io |
File system and I/O operations | File not found, permission denied |
Parse |
Data parsing errors | JSON/YAML parsing failures |
Network |
Network communication failures | HTTP timeouts, DNS resolution |
Config |
Configuration-related issues | Missing config keys, invalid values |
Validation |
Data validation failures | Invalid email, out of range values |
Internal |
Internal system errors | Unexpected state, assertion failures |
CircuitBreakerOpen |
Circuit breaker protection | Service unavailable |
Timeout |
Operation timeouts | Database query timeout |
ResourceExhausted |
Resource limits exceeded | Memory, connections, rate limits |
NotFound |
Resource not found | User not found, endpoint missing |
StateConflict |
State consistency issues | Optimistic locking failures |
Concurrency |
Threading and synchronization | Race conditions, deadlocks |
ExternalService |
Third-party service failures | API errors, service downtime |
MissingValue |
Required values missing | Null pointer, empty required field |
MultipleErrors |
Aggregated error collections | Batch operation failures |
WithRichContext |
Errors with additional context | Enhanced error information |
Style |
Code style and formatting | Linting issues, formatting problems |
Oops |
General purpose wrapper | Wrapping external errors |
Autocorrection Framework
The autocorrection system provides intelligent suggestions for 39 types of programming errors:
🤖 Automatic Fixes (8 types)
Direct code corrections applied automatically:
- Unused imports (
unused_imports
) - Unused variables (
unused_variable
) - Missing semicolons
- Unnecessary clones
- Unnecessary braces
- Unused
mut
keywords - Unreachable code
- Missing imports (
E0433
)
🎯 Interactive Fixes (13 types)
Presents multiple solution options:
- Type mismatches (
E0308
) - Missing lifetimes (
E0106
) - Private field access (
E0603
) - Parameter mismatches (
E0618
/E0617
) - Generic parameter conflicts (
E0403
) - Missing trait implementations (
E0599
/E0277
) - Immutable borrow issues (
E0596
) - Use of moved values (
E0382
) - Non-exhaustive patterns (
E0005
) - Struct/enum parameter mismatches (
E0023
/E0027
)
📖 Manual Guidance (18 types)
Provides detailed guidance for complex issues:
- Division by zero prevention (
E0601
/E0593
) - Function argument corrections (
E0061
) - Reference lifetime issues (
E0515
) - Recursive type definitions (
E0072
) - Unstable feature usage (
E0658
) - Closure lifetime problems (
E0373
) - Network connectivity issues
- File permission problems
- Configuration format issues
- JSON/YAML parsing failures
- TLS certificate validation
- Unsafe
unwrap()
usage - Runtime panic sources
Syntax Generation
Template-based code generation with AST awareness:
use decrust::syntax::{SyntaxGenerator, FixTemplate, TemplateRegistry};
use std::collections::HashMap;
let generator = SyntaxGenerator::new();
// Generate trait implementation
let mut methods = HashMap::new();
methods.insert("display".to_string(), "write!(f, \"Hello\")".to_string());
let trait_impl = generator.generate_trait_impl("Display", "MyStruct", methods);
// Generate import statements
let import = generator.generate_import("std::collections", &["HashMap", "HashSet"]);
// Output: use std::collections::{HashMap, HashSet};
// Create fix templates
let template = FixTemplate::new(
"add_derive",
"Add derive attribute to struct",
"#[derive({traits})]\n{struct_def}"
)
.add_category(ErrorCategory::Style)
.add_error_code("missing_derive");
Configuration
Environment Variables
RUST_BACKTRACE=1
orRUST_LIB_BACKTRACE=1
: Enable backtrace captureRUST_BACKTRACE=full
: Enable full backtrace with all frames
Feature Flags
[dependencies]
decrust = { version = "0.1.0", features = ["tokio", "serde"] }
tokio
: Async circuit breaker supportserde
: Serialization support for error typesrand
: Random jitter for circuit breaker timing
Examples
The examples/
directory contains comprehensive demonstrations:
basic_usage.rs
: Core error handling patterns and reporting- Circuit breaker patterns: Resilience and fault tolerance
- Autocorrection system: Error analysis and fix suggestions
- Syntax generation: Template-based code generation
Run examples with:
cargo run --example basic_usage
Architecture
Decrust is built with a modular architecture:
src/
├── lib.rs # Main error enum and core types
├── backtrace.rs # Environment-aware backtrace system
├── circuit_breaker.rs # Circuit breaker implementation
├── decrust.rs # Autocorrection framework (10,500+ lines)
├── reporter.rs # Multi-format error reporting
├── syntax.rs # AST-aware code generation
└── types.rs # Core type definitions and traits
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Built with ❤️ by ArcMoon Studios
Dependencies
~4–11MB
~121K SLoC