pub mod abstraction;
mod call_error;
pub use abstraction::{
BanSafeError, ConfigSafeError, ErrorMessageAbstraction, GeneralSafeError, LimitSafeError,
SafeErrorMessage, StorageSafeError, ValidationSafeError,
};
pub use call_error::CircuitCallError;
use thiserror::Error;
mod error_impl;
#[derive(Error, Debug)]
pub enum LimiteronError {
#[error("Configuration error: {0}")]
ConfigError(String),
#[error("Storage error: {0}")]
StorageError(#[from] StorageError),
#[error("Rate limit error: {0}")]
LimitError(String),
#[error("Ban error: {0}")]
BanError(String),
#[error("Circuit breaker error: {0}")]
CircuitBreakerError(String),
#[error("Fallback error: {0}")]
FallbackError(String),
#[error("Audit log error: {0}")]
AuditLogError(String),
#[error("Authorization error: {0}")]
AuthorizationError(String),
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("Serialization error: {0}")]
SerdeError(#[from] serde_json::Error),
#[error("YAML parse error: {0}")]
YamlError(#[from] serde_yaml_ng::Error),
#[error("Rate limit exceeded: {0}")]
RateLimitExceeded(String),
#[error("Quota exceeded: {0}")]
QuotaExceeded(String),
#[error("Concurrency limit exceeded: {0}")]
ConcurrencyLimitExceeded(String),
#[error("Throttle queue timeout: {0}")]
Throttled(String),
#[error("Validation error: {0}")]
ValidationError(String),
#[error("Lock acquisition error: {0}")]
LockError(String),
#[error("Time error: {0}")]
TimeError(String),
#[error("Missing dependency: {0}")]
DependencyError(String),
#[error("Parameter mismatch: {0}")]
ParamMismatch(String),
#[error("Unknown error: {0}")]
Other(String),
}
#[derive(Error, Debug, Clone)]
pub enum StorageError {
#[error("Connection error: {0}")]
ConnectionError(String),
#[error("Query error: {0}")]
QueryError(String),
#[error("Timeout error: {0}")]
TimeoutError(String),
#[error("Not found: {0}")]
NotFound(String),
#[error("Authentication error: {0}")]
AuthenticationError(String),
#[error("Permission error: {0}")]
PermissionError(String),
#[error("Invalid configuration: {0}")]
InvalidConfig(String),
#[error("Rate limit: {0}")]
RateLimitError(String),
#[error("Validation error: {0}")]
ValidationError(String),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum CircuitState {
Closed,
Open,
HalfOpen,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct CircuitBreakerStats {
pub state: CircuitState,
pub failure_count: u64,
pub success_count: u64,
pub total_calls: u64,
pub last_failure_time: Option<chrono::DateTime<chrono::Utc>>,
pub last_state_change: Option<chrono::DateTime<chrono::Utc>>,
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct RateLimitMetadata {
pub limit: u64,
pub remaining: u64,
pub reset_at: u64,
pub retry_after: Option<u64>,
pub policy: String,
}
#[derive(Debug, Clone, PartialEq)]
pub struct RejectionMetadata {
pub reason: String,
pub retry_after: u64,
pub limit: u64,
pub reset_at: u64,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Decision {
Allowed(RateLimitMetadata),
Rejected(RejectionMetadata),
Banned(BanInfo),
}
#[derive(Debug, Clone, PartialEq)]
pub struct BanInfo {
reason: String,
banned_until: chrono::DateTime<chrono::Utc>,
ban_times: u32,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ConsumeResult {
pub allowed: bool,
pub remaining: u64,
pub alert_triggered: bool,
pub usage_percent: f64,
}
impl ConsumeResult {
fn usage_percent(consumed: u64, limit: u64) -> f64 {
if limit > 0 {
(consumed as f64 / limit as f64) * 100.0
} else {
0.0
}
}
pub fn allowed(consumed: u64, limit: u64) -> Self {
Self {
allowed: true,
remaining: limit.saturating_sub(consumed),
alert_triggered: false,
usage_percent: Self::usage_percent(consumed, limit),
}
}
pub fn rejected(consumed: u64, limit: u64) -> Self {
Self {
allowed: false,
remaining: limit.saturating_sub(consumed),
alert_triggered: false,
usage_percent: Self::usage_percent(consumed, limit),
}
}
}
pub type LimiteronResult<T> = std::result::Result<T, LimiteronError>;