Expand description
Β§BizError
- Structured Business Error Handling for Rust
A lightweight, flexible business error handling library that provides structured error codes and contextual information while maintaining full compatibility with Rustβs error ecosystem.
Β§π― Design Philosophy
90/10 Principle: 90% of error handling scenarios only need error codes, while 10% require detailed context information.
- Minimal Core:
BizError
trait contains only essential business error identification - Optional Context: Use
ContextualError
wrapper only when detailed context is needed - Zero Overhead: Basic usage scenarios have no additional performance cost
- Full Compatibility: Seamlessly integrates with thiserror and the entire Rust error ecosystem
Β§π Basic Usage with Derive Macro
The simplest way to use BizError
is with the derive macro:
use bizerror::BizError;
#[derive(BizError, thiserror::Error)]
pub enum ApiError {
#[bizcode(4001)]
#[error("Invalid input: {field}")]
ValidationError { field: String },
#[bizcode(8001)]
#[error("Database connection failed")]
DatabaseError(#[from] std::io::Error),
#[bizcode(8006)]
#[error("Request timeout")]
Timeout,
}
// Use the error
let error = ApiError::ValidationError { field: "email".to_string() };
assert_eq!(error.code(), 4001);
assert_eq!(error.name(), "ValidationError");
assert_eq!(error.to_string(), "Invalid input: email"); // Uses Display implementation
Β§ποΈ Automatic Code Assignment
You can configure automatic code assignment for variants without explicit codes:
use bizerror::BizError;
#[derive(BizError, thiserror::Error)]
#[bizconfig(auto_start = 1000, auto_increment = 10)]
pub enum ServiceError {
#[error("Auto-assigned code")]
AutoError1, // code: 1000
#[bizcode(2001)]
#[error("Explicit code")]
ExplicitError, // code: 2001
#[error("Another auto-assigned")]
AutoError2, // code: 1010
}
Β§π§ Advanced Usage with Context
For scenarios requiring detailed context information:
use bizerror::*;
#[derive(BizError, thiserror::Error)]
pub enum ApiError {
#[bizcode(8001)]
#[error("Database connection failed")]
DatabaseError(#[from] std::io::Error),
}
fn load_user_config() -> Result<String, ContextualError<ApiError>> {
std::fs::read_to_string("config.json")
.with_context("Loading user configuration")
}
match load_user_config() {
Ok(config) => println!("Config loaded: {}", config),
Err(e) => {
println!("Error code: {}", e.code());
println!("Context: {}", e.context());
println!("Location: {}", e.location());
}
}
Β§π Custom Code Types
You can use different types for error codes:
use bizerror::BizError;
// String codes
#[derive(BizError, thiserror::Error)]
#[bizconfig(code_type = "&'static str")]
pub enum StringError {
#[bizcode("USER_NOT_FOUND")]
#[error("User not found")]
UserNotFound,
#[error("Auto string code")]
AutoString, // code: "0"
}
// Signed integer codes
#[derive(BizError, thiserror::Error)]
#[bizconfig(code_type = "i32", auto_start = -100)]
pub enum SignedError {
#[error("Negative code")]
NegativeCode, // code: -100
}
Β§π¨ Structured Debug Output
The derive macro automatically generates structured debug output:
let error = ApiError::ValidationError { field: "email".to_string() };
println!("{:?}", error);
// Output: ApiError { variant: "ValidationError", code: 4001, message: "Invalid input: email" }
Β§π Error Chains and Context
Build comprehensive error chains with context:
use bizerror::*;
#[derive(BizError, thiserror::Error)]
pub enum ServiceError {
#[bizcode(8001)]
#[error("Database error: {0}")]
DatabaseError(#[from] std::io::Error),
}
fn complex_operation() -> Result<String, ContextualError<ServiceError>> {
// Multiple layers of context
std::fs::read_to_string("data.json")
.with_context("Loading configuration")
.and_then(|_| {
std::fs::read_to_string("user.json")
.with_context("Loading user data")
})
}
Β§π Best Practices
-
Use meaningful error codes: Group related errors by code ranges
- 1000-1999: Validation errors
- 2000-2999: Authentication errors
- 8000-8999: System errors
-
Leverage automatic assignment: Use
bizconfig
for consistent code spacing -
Add context sparingly: Only use
ContextualError
when you need detailed debugging -
Chain errors properly: Use
#[from]
for automatic conversions -
Document error codes: Include code meanings in your API documentation
StructsΒ§
- BizErrors
- Business errors collection for aggregating multiple errors
- Contextual
Error - Contextual error wrapper (only used when detailed context is needed)
TraitsΒ§
- BizError
- Core business error trait
- BizError
Ext BizError
extension trait- Option
Ext - Option extension trait
- Result
Ext - Result extension trait (simplified)