use apiresponse::{ApiResponse, Response};
use thiserror::Error;
#[derive(Debug, Error, Response)]
#[response(module = "auth.login", base = 1000)]
pub enum AuthError {
#[error("User does not exist")]
UserNotFound,
#[error("Incorrect password")]
PasswordWrong,
#[error("Token expired")]
#[response(status = 401)]
TokenExpired,
#[error("Account is locked")]
#[response(code = 1010, status = 403)] AccountLocked,
}
#[derive(Debug, Error, Response)]
#[response(module = "payment.alipay", base = 2000)]
pub enum PaymentError {
#[error("Insufficient balance")]
InsufficientBalance,
#[error("Payment failed: {0}")]
PaymentFailed(String),
#[error("Order does not exist")]
#[response(status = 404)]
OrderNotFound,
}
#[derive(Debug, Error, Response)]
#[response(module = "database", base = 3000)]
pub enum DbError {
#[error("Connection failed")]
#[response(status = 503)]
ConnectionFailed,
#[error("Query timeout")]
#[response(status = 504)]
QueryTimeout,
#[error("Data does not exist")]
#[response(status = 404)]
RecordNotFound,
}
#[derive(Debug, Error, Response)]
#[response(module = "api")]
pub enum ApiError {
#[error("Authentication failed")]
#[response(code = 4001, status = 401)]
AuthenticationFailed,
#[error(transparent)]
#[response(transparent)]
Auth(#[from] AuthError),
#[error(transparent)]
#[response(transparent)]
Payment(#[from] PaymentError),
#[error(transparent)]
#[response(transparent)]
Database(#[from] DbError),
}
#[derive(Debug, Error, Response)]
#[response(module = "validation")]
pub enum ValidationError {
#[error("Invalid email format")]
#[response(code = 5001, status = 400)]
InvalidEmail,
#[error("Insufficient password strength")]
#[response(code = 5002, status = 400)]
WeakPassword,
#[error("Invalid phone number format")]
#[response(code = 5003, status = 400)]
InvalidPhone,
}
#[derive(Debug, Error, Response)]
#[response(base = 6000)]
pub enum SimpleError {
#[error("Generic error")]
GenericError,
#[error("Another error")]
#[response(status = 500)]
AnotherError,
}
fn main() {
println!("========================================");
println!("Example 1: Basic module prefix formatting");
println!("========================================\n");
let error = AuthError::UserNotFound;
println!("Error: {:?}", error);
println!("Error code: {}", error.error_code());
println!("Module path: {}", error.module_path());
println!("Raw message: {}", error.raw_message());
println!("Formatted message: {}", error.message());
println!("HTTP status code: {}", error.http_status_code());
println!();
let locked = AuthError::AccountLocked;
println!("Locked account error:");
println!(
" Error code: {} (explicitly specified)",
locked.error_code()
);
println!(" Message: {}", locked.message());
println!(" HTTP status code: {}", locked.http_status_code());
println!();
println!("========================================");
println!("Example 2: Two-level module name");
println!("========================================\n");
let payment_error = PaymentError::InsufficientBalance;
println!("Payment error:");
println!(" Module: {}", payment_error.module_path());
println!(" Message: {}", payment_error.message());
println!();
let payment_failed = PaymentError::PaymentFailed("Network timeout".to_string());
println!("Payment failed (with parameter):");
println!(" Message: {}", payment_failed.message());
println!();
println!("========================================");
println!("Example 3: Transparent recursive handling");
println!("========================================\n");
let api_error1 = ApiError::AuthenticationFailed;
println!("API error (direct):");
println!(" Module: {}", api_error1.module_path());
println!(" Message: {}", api_error1.message());
println!(" Error code: {}", api_error1.error_code());
println!();
let api_error2 = ApiError::Auth(AuthError::PasswordWrong);
println!("API error (wrapped auth error):");
println!(" Module: {} (recursed to inner)", api_error2.module_path());
println!(" Message: {} (recursed to inner)", api_error2.message());
println!(" Error code: {} (from AuthError)", api_error2.error_code());
println!();
let api_error3 = ApiError::Database(DbError::ConnectionFailed);
println!("API error (wrapped database error):");
println!(" Module: {} (recursed to inner)", api_error3.module_path());
println!(" Message: {} (recursed to inner)", api_error3.message());
println!(" Error code: {}", api_error3.error_code());
println!(" HTTP status code: {}", api_error3.http_status_code());
println!();
println!("========================================");
println!("Example 4: Integration with ApiResponse");
println!("========================================\n");
let result: Result<String, AuthError> = Err(AuthError::UserNotFound);
let response2: ApiResponse = result.into();
println!("Converting ApiResponse from Result:");
println!(" {}", serde_json::to_string_pretty(&response2).unwrap());
println!();
println!("========================================");
println!("Example 5: Usage without base attribute");
println!("========================================\n");
let validation_error = ValidationError::InvalidEmail;
println!("Validation error (no base, code explicitly specified):");
println!(" Error code: {}", validation_error.error_code());
println!(" Message: {}", validation_error.message());
println!(
" HTTP status code: {}",
validation_error.http_status_code()
);
println!();
println!("========================================");
println!("Example 6: Usage without module attribute");
println!("========================================\n");
let simple_error = SimpleError::GenericError;
println!("Simple error (no module, empty prefix):");
println!(" Error code: {}", simple_error.error_code());
println!(" Module path: \"{}\"", simple_error.module_path());
println!(" Raw message: {}", simple_error.raw_message());
println!(" Formatted message: {}", simple_error.message());
println!(" Note: No module prefix since module is empty");
println!();
println!("========================================");
println!("All examples completed!");
println!("========================================");
}