1use crate::error::QmlError;
2use thiserror::Error;
3
4#[derive(Error, Debug)]
12pub enum StorageError {
13 #[error("Storage connection error: {message}")]
15 Connection {
16 message: String,
17 #[source]
18 source: Option<Box<dyn std::error::Error + Send + Sync>>,
19 },
20
21 #[error("Serialization error: {message}")]
24 Serialization {
25 message: String,
26 #[source]
27 source: Option<Box<dyn std::error::Error + Send + Sync>>,
28 },
29
30 #[error("Deserialization error: {message}")]
34 Deserialization {
35 message: String,
36 #[source]
37 source: Option<Box<dyn std::error::Error + Send + Sync>>,
38 },
39
40 #[error("Job not found: {job_id}")]
42 JobNotFound { job_id: String },
43
44 #[error("Storage operation timed out after {timeout_ms}ms")]
46 Timeout { timeout_ms: u64 },
47
48 #[error("Storage is unavailable: {reason}")]
50 Unavailable { reason: String },
51
52 #[error("Storage configuration error: {message}")]
54 Configuration { message: String },
55
56 #[error("Storage operation failed: {message}")]
62 OperationFailed {
63 message: String,
64 #[source]
65 source: Option<Box<dyn std::error::Error + Send + Sync>>,
66 },
67
68 #[error("Storage capacity exceeded: {message}")]
70 CapacityExceeded { message: String },
71
72 #[error("Concurrent modification detected for job: {job_id}")]
74 ConcurrentModification { job_id: String },
75
76 #[error("Migration error: {message}")]
78 MigrationError { message: String },
79
80 #[error("Invalid job data: {message}")]
82 InvalidJobData { message: String },
83}
84
85impl StorageError {
86 pub fn connection<S: Into<String>>(message: S) -> Self {
88 Self::Connection {
89 message: message.into(),
90 source: None,
91 }
92 }
93
94 pub fn connection_with_source<S: Into<String>>(
96 message: S,
97 source: Box<dyn std::error::Error + Send + Sync>,
98 ) -> Self {
99 Self::Connection {
100 message: message.into(),
101 source: Some(source),
102 }
103 }
104
105 pub fn serialization<S: Into<String>>(message: S) -> Self {
107 Self::Serialization {
108 message: message.into(),
109 source: None,
110 }
111 }
112
113 pub fn serialization_with_source<S: Into<String>>(
115 message: S,
116 source: Box<dyn std::error::Error + Send + Sync>,
117 ) -> Self {
118 Self::Serialization {
119 message: message.into(),
120 source: Some(source),
121 }
122 }
123
124 pub fn deserialization<S: Into<String>>(message: S) -> Self {
126 Self::Deserialization {
127 message: message.into(),
128 source: None,
129 }
130 }
131
132 pub fn deserialization_with_source<S: Into<String>>(
134 message: S,
135 source: Box<dyn std::error::Error + Send + Sync>,
136 ) -> Self {
137 Self::Deserialization {
138 message: message.into(),
139 source: Some(source),
140 }
141 }
142
143 pub fn job_not_found<S: Into<String>>(job_id: S) -> Self {
145 Self::JobNotFound {
146 job_id: job_id.into(),
147 }
148 }
149
150 pub fn timeout(timeout_ms: u64) -> Self {
152 Self::Timeout { timeout_ms }
153 }
154
155 pub fn unavailable<S: Into<String>>(reason: S) -> Self {
157 Self::Unavailable {
158 reason: reason.into(),
159 }
160 }
161
162 pub fn configuration<S: Into<String>>(message: S) -> Self {
164 Self::Configuration {
165 message: message.into(),
166 }
167 }
168
169 pub fn operation_failed<S: Into<String>>(message: S) -> Self {
172 Self::OperationFailed {
173 message: message.into(),
174 source: None,
175 }
176 }
177
178 pub fn operation_failed_with_source<S: Into<String>>(
180 message: S,
181 source: Box<dyn std::error::Error + Send + Sync>,
182 ) -> Self {
183 Self::OperationFailed {
184 message: message.into(),
185 source: Some(source),
186 }
187 }
188
189 pub fn capacity_exceeded<S: Into<String>>(message: S) -> Self {
191 Self::CapacityExceeded {
192 message: message.into(),
193 }
194 }
195
196 pub fn concurrent_modification<S: Into<String>>(job_id: S) -> Self {
198 Self::ConcurrentModification {
199 job_id: job_id.into(),
200 }
201 }
202
203 pub fn conn_err<M, E>(message: M, source: E) -> Self
207 where
208 M: Into<String>,
209 E: std::error::Error + Send + Sync + 'static,
210 {
211 Self::Connection {
212 message: message.into(),
213 source: Some(Box::new(source)),
214 }
215 }
216
217 pub fn ser_err<M, E>(message: M, source: E) -> Self
219 where
220 M: Into<String>,
221 E: std::error::Error + Send + Sync + 'static,
222 {
223 Self::Serialization {
224 message: message.into(),
225 source: Some(Box::new(source)),
226 }
227 }
228
229 pub fn de_err<M, E>(message: M, source: E) -> Self
231 where
232 M: Into<String>,
233 E: std::error::Error + Send + Sync + 'static,
234 {
235 Self::Deserialization {
236 message: message.into(),
237 source: Some(Box::new(source)),
238 }
239 }
240
241 pub fn op_err<M, E>(message: M, source: E) -> Self
243 where
244 M: Into<String>,
245 E: std::error::Error + Send + Sync + 'static,
246 {
247 Self::OperationFailed {
248 message: message.into(),
249 source: Some(Box::new(source)),
250 }
251 }
252}
253
254impl From<StorageError> for QmlError {
256 fn from(err: StorageError) -> Self {
257 match err {
258 StorageError::JobNotFound { job_id } => QmlError::JobNotFound { job_id },
259 StorageError::Serialization { message, .. }
264 | StorageError::Deserialization { message, .. } => {
265 QmlError::SerializationError { message }
266 }
267 _ => QmlError::StorageError {
268 message: err.to_string(),
269 },
270 }
271 }
272}