use std::fmt::Debug;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum DbError {
#[error("Database connection error: {0}")]
#[allow(dead_code)]
Connection(String),
#[error("Database query error: {0}")]
#[allow(dead_code)]
Query(String),
#[error("Database transaction error: {0}")]
#[allow(dead_code)]
Transaction(String),
#[error("Database pool error: {0}")]
#[allow(dead_code)]
Pool(String),
#[error("Database configuration error: {0}")]
#[allow(dead_code)]
Config(String),
#[error("Database migration error: {0}")]
#[allow(dead_code)]
Migration(String),
#[error("Database validation error: {0}")]
#[allow(dead_code)]
Validation(String),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("Serialization error: {0}")]
Serialization(#[from] serde_json::Error),
}
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Error, Debug)]
pub enum Error {
#[error("Database error: {0}")]
Database(#[from] sqlx::Error),
#[error("Pool error: {0}")]
Pool(String),
#[error("Transaction error: {0}")]
Transaction(String),
#[error("Query error: {0}")]
Query(String),
#[error("Value conversion error: {0}")]
Conversion(String),
#[error("Configuration error: {0}")]
Config(String),
#[error(transparent)]
Other(#[from] anyhow::Error),
#[error("Row not found")]
RowNotFound,
}
impl Error {
pub fn is_not_found(&self) -> bool {
matches!(self, Error::RowNotFound)
}
pub fn is_unique_violation(&self) -> bool {
matches!(self, Error::Database(e) if e.as_database_error()
.map(|e| matches!(e.kind(), sqlx::error::ErrorKind::UniqueViolation))
.unwrap_or(false))
}
pub fn is_foreign_key_violation(&self) -> bool {
matches!(self, Error::Database(e) if e.as_database_error()
.map(|e| matches!(e.kind(), sqlx::error::ErrorKind::ForeignKeyViolation))
.unwrap_or(false))
}
}