#[derive(Debug, thiserror::Error)]
pub enum DbError {
#[error(transparent)]
Connection(#[from] sea_orm::DbErr),
#[error("Configuration error: {0}")]
Config(String),
#[error("Permission denied: {0}")]
Permission(String),
#[error("Transaction error: {0}")]
Transaction(String),
#[error("Migration error: {0}")]
Migration(String),
#[cfg(feature = "validation")]
#[error("Validation error: {0}")]
Validation(String),
}
impl DbError {
pub fn new(error: sea_orm::DbErr) -> Self {
Self::Connection(error)
}
pub fn message(&self) -> String {
match self {
DbError::Connection(e) => e.to_string(),
DbError::Config(msg) => msg.clone(),
DbError::Permission(msg) => msg.clone(),
DbError::Transaction(msg) => msg.clone(),
DbError::Migration(msg) => msg.clone(),
#[cfg(feature = "validation")]
DbError::Validation(msg) => msg.clone(),
}
}
}
impl From<String> for DbError {
fn from(msg: String) -> Self {
Self::Config(msg)
}
}
impl From<&str> for DbError {
fn from(msg: &str) -> Self {
Self::Config(msg.to_string())
}
}
#[derive(Debug, thiserror::Error)]
pub enum PoolError {
#[error("Failed to acquire connection within timeout")]
AcquireTimeout,
#[error("Connection pool exhausted")]
PoolExhausted,
#[error("Failed to create connection: {0}")]
ConnectionFailed(String),
#[error("Health check failed: {0}")]
HealthCheckFailed(String),
}
pub use crate::domain::permission::PermissionError;
#[derive(Debug, thiserror::Error)]
pub enum MigrationError {
#[error("Migration file not found: {0}")]
FileNotFound(String),
#[error("Failed to parse migration file: {0}")]
ParseError(String),
#[error("Migration execution failed: {0}")]
ExecutionError(String),
#[error("Migration version conflict: {0}")]
VersionConflict(String),
#[error("Migration rollback failed: {0}")]
RollbackError(String),
}
#[derive(Debug, thiserror::Error)]
pub enum AuditError {
#[error("Failed to write audit log: {0}")]
WriteError(String),
#[error("Failed to serialize audit data: {0}")]
SerializationError(String),
#[error("Invalid audit configuration: {0}")]
ConfigError(String),
}
pub type DbResult<T> = Result<T, DbError>;
pub type PermissionResult<T> = Result<T, PermissionError>;
pub type PoolResult<T> = Result<T, PoolError>;
pub type ConfigResult<T> = Result<T, crate::foundation::config::ConfigError>;
pub type MigrationResult<T> = Result<T, MigrationError>;
pub type AuditResult<T> = Result<T, AuditError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_db_error_creation() {
let db_err = sea_orm::DbErr::Custom("test error".to_string());
let error = DbError::new(db_err);
assert!(matches!(error, DbError::Connection(_)));
}
#[test]
fn test_db_error_from_string() {
let error: DbError = "custom error message".into();
assert!(matches!(error, DbError::Config(msg) if msg == "custom error message"));
}
#[test]
fn test_db_error_from_str() {
let error: DbError = "str error".into();
assert!(matches!(error, DbError::Config(msg) if msg == "str error"));
}
#[test]
fn test_db_error_variants() {
let config_err = DbError::Config("config issue".to_string());
assert!(matches!(config_err, DbError::Config(_)));
let perm_err = DbError::Permission("access denied".to_string());
assert!(matches!(perm_err, DbError::Permission(_)));
let tx_err = DbError::Transaction("tx failed".to_string());
assert!(matches!(tx_err, DbError::Transaction(_)));
let mig_err = DbError::Migration("migration failed".to_string());
assert!(matches!(mig_err, DbError::Migration(_)));
}
#[test]
fn test_pool_error_display() {
let error = PoolError::AcquireTimeout;
assert_eq!(error.to_string(), "Failed to acquire connection within timeout");
let error = PoolError::ConnectionFailed("network issue".to_string());
assert!(error.to_string().contains("network issue"));
}
#[test]
fn test_permission_error_display() {
let error = PermissionError::Denied {
resource: "users".to_string(),
operation: "delete".to_string(),
};
let msg = error.to_string();
assert!(msg.contains("users"));
assert!(msg.contains("delete"));
let error = PermissionError::RoleNotFound("admin".to_string());
assert!(error.to_string().contains("admin"));
}
#[test]
fn test_migration_error_display() {
let error = MigrationError::FileNotFound("v001.sql".to_string());
assert!(error.to_string().contains("v001.sql"));
let error = MigrationError::VersionConflict("v002".to_string());
assert!(error.to_string().contains("v002"));
}
#[test]
fn test_audit_error_display() {
let error = AuditError::WriteError("disk full".to_string());
assert!(error.to_string().contains("disk full"));
let error = AuditError::SerializationError("invalid JSON".to_string());
assert!(error.to_string().contains("invalid JSON"));
}
}