use thiserror::Error;
#[derive(Debug, Error)]
pub enum OrmError {
#[error("Record not found")]
NotFound,
#[error("Database error: {0}")]
Database(#[from] sqlx::Error),
#[error("Validation failed: {0}")]
Validation(String),
#[error("Forbidden: {0}")]
Forbidden(String),
#[error("Unique constraint violation on field `{field}`")]
UniqueViolation { field: String },
#[error("Foreign key violation: {0}")]
ForeignKeyViolation(String),
#[error("Encryption error: {0}")]
Encryption(String),
#[error("Decryption error: {0}")]
Decryption(String),
#[error("Hashing error: {0}")]
Hashing(String),
#[error("Type conversion error: {0}")]
TypeConversion(String),
#[error("Migration error: {0}")]
Migration(String),
#[error("Configuration error: {0}")]
Config(String),
#[error("Transaction error: {0}")]
Transaction(String),
#[error("Pool timeout")]
PoolTimeout,
#[error("Serialization error: {0}")]
Serialization(#[from] serde_json::Error),
#[error("{0}")]
Custom(String),
}
impl OrmError {
pub fn from_sqlx(err: sqlx::Error) -> Self {
if let sqlx::Error::Database(ref db_err) = err {
let msg = db_err.message();
if db_err.code().as_deref() == Some("23505") {
let field = db_err.constraint().unwrap_or("unknown").to_string();
return OrmError::UniqueViolation { field };
}
if db_err.code().as_deref() == Some("23503") {
return OrmError::ForeignKeyViolation(msg.to_string());
}
}
OrmError::Database(err)
}
}
pub type OrmResult<T> = Result<T, OrmError>;