use crate::error::QmlError;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum StorageError {
#[error("Storage connection error: {message}")]
Connection {
message: String,
#[source]
source: Option<Box<dyn std::error::Error + Send + Sync>>,
},
#[error("Serialization error: {message}")]
Serialization {
message: String,
#[source]
source: Option<Box<dyn std::error::Error + Send + Sync>>,
},
#[error("Deserialization error: {message}")]
Deserialization {
message: String,
#[source]
source: Option<Box<dyn std::error::Error + Send + Sync>>,
},
#[error("Job not found: {job_id}")]
JobNotFound { job_id: String },
#[error("Storage operation timed out after {timeout_ms}ms")]
Timeout { timeout_ms: u64 },
#[error("Storage is unavailable: {reason}")]
Unavailable { reason: String },
#[error("Storage configuration error: {message}")]
Configuration { message: String },
#[error("Storage operation failed: {message}")]
OperationFailed {
message: String,
#[source]
source: Option<Box<dyn std::error::Error + Send + Sync>>,
},
#[error("Storage capacity exceeded: {message}")]
CapacityExceeded { message: String },
#[error("Concurrent modification detected for job: {job_id}")]
ConcurrentModification { job_id: String },
#[error("Migration error: {message}")]
MigrationError { message: String },
#[error("Invalid job data: {message}")]
InvalidJobData { message: String },
}
impl StorageError {
pub fn connection<S: Into<String>>(message: S) -> Self {
Self::Connection {
message: message.into(),
source: None,
}
}
pub fn connection_with_source<S: Into<String>>(
message: S,
source: Box<dyn std::error::Error + Send + Sync>,
) -> Self {
Self::Connection {
message: message.into(),
source: Some(source),
}
}
pub fn serialization<S: Into<String>>(message: S) -> Self {
Self::Serialization {
message: message.into(),
source: None,
}
}
pub fn serialization_with_source<S: Into<String>>(
message: S,
source: Box<dyn std::error::Error + Send + Sync>,
) -> Self {
Self::Serialization {
message: message.into(),
source: Some(source),
}
}
pub fn deserialization<S: Into<String>>(message: S) -> Self {
Self::Deserialization {
message: message.into(),
source: None,
}
}
pub fn deserialization_with_source<S: Into<String>>(
message: S,
source: Box<dyn std::error::Error + Send + Sync>,
) -> Self {
Self::Deserialization {
message: message.into(),
source: Some(source),
}
}
pub fn job_not_found<S: Into<String>>(job_id: S) -> Self {
Self::JobNotFound {
job_id: job_id.into(),
}
}
pub fn timeout(timeout_ms: u64) -> Self {
Self::Timeout { timeout_ms }
}
pub fn unavailable<S: Into<String>>(reason: S) -> Self {
Self::Unavailable {
reason: reason.into(),
}
}
pub fn configuration<S: Into<String>>(message: S) -> Self {
Self::Configuration {
message: message.into(),
}
}
pub fn operation_failed<S: Into<String>>(message: S) -> Self {
Self::OperationFailed {
message: message.into(),
source: None,
}
}
pub fn operation_failed_with_source<S: Into<String>>(
message: S,
source: Box<dyn std::error::Error + Send + Sync>,
) -> Self {
Self::OperationFailed {
message: message.into(),
source: Some(source),
}
}
pub fn capacity_exceeded<S: Into<String>>(message: S) -> Self {
Self::CapacityExceeded {
message: message.into(),
}
}
pub fn concurrent_modification<S: Into<String>>(job_id: S) -> Self {
Self::ConcurrentModification {
job_id: job_id.into(),
}
}
pub fn conn_err<M, E>(message: M, source: E) -> Self
where
M: Into<String>,
E: std::error::Error + Send + Sync + 'static,
{
Self::Connection {
message: message.into(),
source: Some(Box::new(source)),
}
}
pub fn ser_err<M, E>(message: M, source: E) -> Self
where
M: Into<String>,
E: std::error::Error + Send + Sync + 'static,
{
Self::Serialization {
message: message.into(),
source: Some(Box::new(source)),
}
}
pub fn de_err<M, E>(message: M, source: E) -> Self
where
M: Into<String>,
E: std::error::Error + Send + Sync + 'static,
{
Self::Deserialization {
message: message.into(),
source: Some(Box::new(source)),
}
}
pub fn op_err<M, E>(message: M, source: E) -> Self
where
M: Into<String>,
E: std::error::Error + Send + Sync + 'static,
{
Self::OperationFailed {
message: message.into(),
source: Some(Box::new(source)),
}
}
}
impl From<StorageError> for QmlError {
fn from(err: StorageError) -> Self {
match err {
StorageError::JobNotFound { job_id } => QmlError::JobNotFound { job_id },
StorageError::Serialization { message, .. }
| StorageError::Deserialization { message, .. } => {
QmlError::SerializationError { message }
}
_ => QmlError::StorageError {
message: err.to_string(),
},
}
}
}