use thiserror::Error;
#[derive(Error, Debug)]
pub enum StorageError {
#[error("Database connection error: {0}")]
ConnectionError(String),
#[error("Query execution error: {0}")]
QueryError(String),
#[error("Serialization error: {0}")]
SerializationError(String),
#[error("Deserialization error: {0}")]
DeserializationError(String),
#[error("Data integrity error: {0}")]
IntegrityError(String),
#[error("Concurrency conflict: {0}")]
ConcurrencyError(String),
#[error("Resource not found: {0}")]
NotFoundError(String),
#[error("Configuration error: {0}")]
ConfigError(String),
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("Other error: {0}")]
Other(#[from] anyhow::Error),
}
pub type StorageResult<T> = Result<T, StorageError>;
impl From<actr_protocol::ActrError> for StorageError {
fn from(err: actr_protocol::ActrError) -> Self {
StorageError::Other(anyhow::anyhow!("Actor error: {err}"))
}
}
#[cfg(feature = "sqlite")]
impl From<rusqlite::Error> for StorageError {
fn from(err: rusqlite::Error) -> Self {
match err {
rusqlite::Error::SqliteFailure(sqlite_err, msg) => {
let message = format!(
"SQLite error: {:?} - {}",
sqlite_err.code,
msg.unwrap_or_default()
);
match sqlite_err.code {
rusqlite::ErrorCode::DatabaseBusy | rusqlite::ErrorCode::DatabaseLocked => {
StorageError::ConcurrencyError(message)
}
rusqlite::ErrorCode::ConstraintViolation => {
StorageError::IntegrityError(message)
}
rusqlite::ErrorCode::NotFound => StorageError::NotFoundError(message),
_ => StorageError::QueryError(message),
}
}
_ => StorageError::QueryError(err.to_string()),
}
}
}