mockforge_core/encryption/
errors.rs1use std::fmt;
7use thiserror::Error;
8
9#[derive(Error, Debug)]
11pub enum EncryptionError {
12 #[error("Invalid key: {message}")]
14 InvalidKey { message: String },
15
16 #[error("Invalid nonce: {message}")]
18 InvalidNonce { message: String },
19
20 #[error("Authentication failed: {message}")]
22 AuthenticationFailed { message: String },
23
24 #[error("Invalid ciphertext: {message}")]
26 InvalidCiphertext { message: String },
27
28 #[error("Key derivation failed: {message}")]
30 KeyDerivationFailed { message: String },
31
32 #[error("Key not found: {key_id}")]
34 KeyNotFound { key_id: String },
35
36 #[error("Access denied: {message}")]
38 AccessDenied { message: String },
39
40 #[error("Key store error: {message}")]
42 KeyStoreError { message: String },
43
44 #[error("Random generation failed: {message}")]
46 RandomGenerationFailed { message: String },
47
48 #[error("Invalid algorithm: {message}")]
50 InvalidAlgorithm { message: String },
51
52 #[error("Cipher operation failed: {message}")]
54 CipherOperationFailed { message: String },
55
56 #[error("Base64 operation failed: {message}")]
58 Base64Error { message: String },
59
60 #[error("Serialization failed: {message}")]
62 SerializationError { message: String },
63
64 #[error("Template processing failed: {message}")]
66 TemplateError { message: String },
67
68 #[error("Auto-encryption configuration error: {message}")]
70 AutoEncryptionConfigError { message: String },
71
72 #[error("Workspace encryption error: {message}")]
74 Workspace { message: String },
75
76 #[error("Encryption error: {message}")]
78 Generic { message: String },
79}
80
81impl EncryptionError {
82 pub fn invalid_key(message: impl Into<String>) -> Self {
84 Self::InvalidKey {
85 message: message.into(),
86 }
87 }
88
89 pub fn invalid_nonce(message: impl Into<String>) -> Self {
91 Self::InvalidNonce {
92 message: message.into(),
93 }
94 }
95
96 pub fn authentication_failed(message: impl Into<String>) -> Self {
98 Self::AuthenticationFailed {
99 message: message.into(),
100 }
101 }
102
103 pub fn invalid_ciphertext(message: impl Into<String>) -> Self {
105 Self::InvalidCiphertext {
106 message: message.into(),
107 }
108 }
109
110 pub fn key_derivation_failed(message: impl Into<String>) -> Self {
112 Self::KeyDerivationFailed {
113 message: message.into(),
114 }
115 }
116
117 pub fn key_not_found(key_id: impl Into<String>) -> Self {
119 Self::KeyNotFound {
120 key_id: key_id.into(),
121 }
122 }
123
124 pub fn access_denied(message: impl Into<String>) -> Self {
126 Self::AccessDenied {
127 message: message.into(),
128 }
129 }
130
131 pub fn key_store_error(message: impl Into<String>) -> Self {
133 Self::KeyStoreError {
134 message: message.into(),
135 }
136 }
137
138 pub fn random_generation_failed(message: impl Into<String>) -> Self {
140 Self::RandomGenerationFailed {
141 message: message.into(),
142 }
143 }
144
145 pub fn invalid_algorithm(message: impl Into<String>) -> Self {
147 Self::InvalidAlgorithm {
148 message: message.into(),
149 }
150 }
151
152 pub fn cipher_operation_failed(message: impl Into<String>) -> Self {
154 Self::CipherOperationFailed {
155 message: message.into(),
156 }
157 }
158
159 pub fn base64_error(message: impl Into<String>) -> Self {
161 Self::Base64Error {
162 message: message.into(),
163 }
164 }
165
166 pub fn serialization_error(message: impl Into<String>) -> Self {
168 Self::SerializationError {
169 message: message.into(),
170 }
171 }
172
173 pub fn template_error(message: impl Into<String>) -> Self {
175 Self::TemplateError {
176 message: message.into(),
177 }
178 }
179
180 pub fn auto_encryption_config_error(message: impl Into<String>) -> Self {
182 Self::AutoEncryptionConfigError {
183 message: message.into(),
184 }
185 }
186
187 pub fn workspace_encryption_error(message: impl Into<String>) -> Self {
189 Self::Workspace {
190 message: message.into(),
191 }
192 }
193
194 pub fn generic(message: impl Into<String>) -> Self {
196 Self::Generic {
197 message: message.into(),
198 }
199 }
200
201 pub fn is_recoverable(&self) -> bool {
203 match self {
204 Self::InvalidKey { .. }
205 | Self::InvalidNonce { .. }
206 | Self::AuthenticationFailed { .. }
207 | Self::InvalidCiphertext { .. }
208 | Self::KeyNotFound { .. }
209 | Self::InvalidAlgorithm { .. }
210 | Self::Base64Error { .. }
211 | Self::SerializationError { .. }
212 | Self::TemplateError { .. }
213 | Self::AutoEncryptionConfigError { .. } => false,
214
215 Self::KeyDerivationFailed { .. }
216 | Self::AccessDenied { .. }
217 | Self::KeyStoreError { .. }
218 | Self::RandomGenerationFailed { .. }
219 | Self::CipherOperationFailed { .. }
220 | Self::Workspace { .. }
221 | Self::Generic { .. } => true,
222 }
223 }
224
225 pub fn severity(&self) -> ErrorSeverity {
227 match self {
228 Self::AuthenticationFailed { .. } | Self::AccessDenied { .. } => {
229 ErrorSeverity::Critical
230 }
231
232 Self::InvalidKey { .. }
233 | Self::InvalidNonce { .. }
234 | Self::InvalidCiphertext { .. }
235 | Self::InvalidAlgorithm { .. } => ErrorSeverity::High,
236
237 Self::KeyDerivationFailed { .. }
238 | Self::KeyStoreError { .. }
239 | Self::RandomGenerationFailed { .. }
240 | Self::CipherOperationFailed { .. } => ErrorSeverity::Medium,
241
242 Self::Base64Error { .. }
243 | Self::SerializationError { .. }
244 | Self::TemplateError { .. }
245 | Self::AutoEncryptionConfigError { .. }
246 | Self::Workspace { .. }
247 | Self::Generic { .. } => ErrorSeverity::Low,
248
249 Self::KeyNotFound { .. } => ErrorSeverity::Info,
250 }
251 }
252}
253
254#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
256pub enum ErrorSeverity {
257 Info,
259 Low,
261 Medium,
263 High,
265 Critical,
267}
268
269pub type EncryptionResult<T> = Result<T, EncryptionError>;
271
272#[derive(Debug, Clone)]
274pub struct ErrorContext {
275 pub operation: String,
277 pub context: HashMap<String, String>,
279 pub timestamp: chrono::DateTime<chrono::Utc>,
281}
282
283impl ErrorContext {
284 pub fn new(operation: impl Into<String>) -> Self {
286 Self {
287 operation: operation.into(),
288 context: HashMap::new(),
289 timestamp: chrono::Utc::now(),
290 }
291 }
292
293 pub fn with_context(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
295 self.context.insert(key.into(), value.into());
296 self
297 }
298}
299
300#[derive(Debug)]
302pub struct ContextualError {
303 pub error: EncryptionError,
305 pub context: ErrorContext,
307}
308
309impl fmt::Display for ContextualError {
310 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
311 write!(
312 f,
313 "Encryption error in {} at {}: {} (context: {:?})",
314 self.context.operation, self.context.timestamp, self.error, self.context.context
315 )
316 }
317}
318
319impl std::error::Error for ContextualError {
320 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
321 Some(&self.error)
322 }
323}
324
325#[derive(Debug, Clone)]
327pub enum ErrorRecoveryStrategy {
328 RetryWithBackoff {
330 max_attempts: usize,
331 base_delay_ms: u64,
332 },
333 FallbackMethod,
335 SkipEncryption,
337 ManualIntervention,
339 FailFast,
341}
342
343impl EncryptionError {
344 pub fn suggested_recovery(&self) -> ErrorRecoveryStrategy {
346 match self {
347 Self::RandomGenerationFailed { .. } => ErrorRecoveryStrategy::RetryWithBackoff {
348 max_attempts: 3,
349 base_delay_ms: 100,
350 },
351
352 Self::KeyStoreError { .. } | Self::KeyDerivationFailed { .. } => {
353 ErrorRecoveryStrategy::ManualIntervention
354 }
355
356 Self::AuthenticationFailed { .. } | Self::AccessDenied { .. } => {
357 ErrorRecoveryStrategy::FailFast
358 }
359
360 Self::InvalidKey { .. } | Self::InvalidNonce { .. } => {
361 ErrorRecoveryStrategy::FallbackMethod
362 }
363
364 _ => ErrorRecoveryStrategy::RetryWithBackoff {
365 max_attempts: 2,
366 base_delay_ms: 50,
367 },
368 }
369 }
370
371 pub fn with_context(self, context: ErrorContext) -> ContextualError {
373 ContextualError {
374 error: self,
375 context,
376 }
377 }
378}
379
380use std::collections::HashMap;