train_station/serialization/core/error.rs
1//! Core error types for serialization operations
2//!
3//! This module provides the fundamental error types and result aliases used throughout
4//! the serialization system. It defines the main `SerializationError` enum that covers
5//! all possible failure modes during serialization and deserialization operations.
6//!
7//! # Purpose
8//!
9//! The error system provides:
10//! - Comprehensive error coverage for all serialization operations
11//! - Detailed context for debugging and error recovery
12//! - Format-specific error delegation to specialized modules
13//! - Standard error trait implementations for integration
14//! - Convenient result type aliases for cleaner code
15//!
16//! # Error Categories
17//!
18//! The `SerializationError` enum covers several categories of errors:
19//! - **I/O Errors**: File operations, network issues, stream handling
20//! - **Format Errors**: JSON and binary format-specific parsing errors
21//! - **Validation Errors**: Data validation failures during deserialization
22//! - **Shape Errors**: Tensor dimension mismatches
23//! - **Memory Errors**: Allocation failures and resource constraints
24//! - **Custom Errors**: Generic errors with custom messages
25//!
26//! # Usage Patterns
27//!
28//! The error system provides comprehensive error handling for all serialization
29//! operations with detailed context for debugging and error recovery.
30//!
31//! # Error Handling
32//!
33//! All serialization operations return `SerializationResult<T>` which provides:
34//! - Detailed error context for debugging
35//! - Source error chaining for root cause analysis
36//! - Human-readable error messages
37//! - Structured error data for programmatic handling
38//!
39//! # Thread Safety
40//!
41//! All error types are thread-safe and can be shared across threads without
42//! additional synchronization.
43
44use std::fmt;
45use std::io;
46
47/// Result type for serialization operations
48///
49/// This type alias provides a convenient way to express the result of any
50/// serialization or deserialization operation. It uses the standard `Result`
51/// type with `SerializationError` as the error variant.
52///
53
54pub type SerializationResult<T> = Result<T, SerializationError>;
55
56/// Main error type for serialization operations
57///
58/// This enum covers all possible failure modes during serialization and deserialization,
59/// providing detailed context for debugging and error recovery. Format-specific errors
60/// are delegated to their respective modules while maintaining a unified error interface.
61///
62/// # Error Variants
63///
64/// The enum provides comprehensive coverage of serialization failure modes:
65/// - **I/O errors**: File operations, network issues, stream handling
66/// - **Format errors**: JSON and binary format-specific parsing errors
67/// - **Validation errors**: Data validation failures during deserialization
68/// - **Shape errors**: Tensor dimension mismatches
69/// - **Memory errors**: Allocation failures and resource constraints
70/// - **Custom errors**: Generic errors with custom messages
71///
72/// # Error Context
73///
74/// Each error variant provides detailed context to aid in debugging:
75/// - Field names and validation messages for validation errors
76/// - Expected vs actual tensor dimensions for shape errors
77/// - Memory allocation details for allocation failures
78/// - Format-specific error information for parsing errors
79///
80/// # Thread Safety
81///
82/// This type is thread-safe and can be shared across threads without
83/// additional synchronization.
84///
85
86#[derive(Debug)]
87pub enum SerializationError {
88 /// I/O errors during file operations, network issues, or stream handling
89 ///
90 /// This variant wraps standard I/O errors that occur during serialization
91 /// operations, such as file reading/writing, network communication, or
92 /// stream processing. The underlying I/O error is preserved for detailed
93 /// error analysis.
94 ///
95 /// # Common Causes
96 ///
97 /// - File not found or permission denied
98 /// - Disk space exhaustion
99 /// - Network connectivity issues
100 /// - Stream corruption or interruption
101 /// - Device I/O failures
102 Io(io::Error),
103
104 /// JSON-specific format and parsing errors
105 ///
106 /// This variant delegates to the JSON module's error type for format-specific
107 /// JSON parsing and validation errors. It provides detailed information about
108 /// JSON syntax errors, structural issues, and parsing failures.
109 ///
110 /// # Common Causes
111 ///
112 /// - Invalid JSON syntax
113 /// - Malformed JSON structure
114 /// - Encoding issues
115 /// - Unexpected token types
116 /// - JSON depth limits exceeded
117 Json(crate::serialization::json::JsonError),
118
119 /// Binary-specific format and parsing errors
120 ///
121 /// This variant delegates to the binary module's error type for format-specific
122 /// binary parsing and validation errors. It provides detailed information about
123 /// binary format issues, corruption, and parsing failures.
124 ///
125 /// # Common Causes
126 ///
127 /// - Invalid binary format
128 /// - Corrupted binary data
129 /// - Version mismatches
130 /// - Magic number validation failures
131 /// - Truncated binary streams
132 Binary(crate::serialization::binary::BinaryError),
133
134 /// Data validation failed during deserialization
135 ///
136 /// This variant indicates that data validation failed during the deserialization
137 /// process. It provides the specific field name and a human-readable message
138 /// explaining why the validation failed.
139 ///
140 /// # Fields
141 ///
142 /// * `field` - Name of the field that failed validation
143 /// * `message` - Human-readable message explaining why validation failed
144 ///
145 /// # Common Causes
146 ///
147 /// - Invalid field values
148 /// - Missing required fields
149 /// - Type conversion failures
150 /// - Constraint violations
151 /// - Business logic validation failures
152 ValidationFailed {
153 /// Name of the field that failed validation
154 field: String,
155 /// Human-readable message explaining why validation failed
156 message: String,
157 },
158
159 /// Tensor shape or size mismatch
160 ///
161 /// This variant indicates that a tensor's dimensions don't match the expected
162 /// shape during deserialization or validation. It provides both the expected
163 /// and actual dimensions for debugging.
164 ///
165 /// # Fields
166 ///
167 /// * `expected_dims` - Expected tensor dimensions
168 /// * `found_dims` - Actual tensor dimensions found
169 ///
170 /// # Common Causes
171 ///
172 /// - Incorrect tensor serialization
173 /// - Version incompatibilities
174 /// - Manual data corruption
175 /// - Serialization format changes
176 /// - Dimension calculation errors
177 ShapeMismatch {
178 /// Expected tensor dimensions
179 expected_dims: Vec<usize>,
180 /// Actual tensor dimensions found
181 found_dims: Vec<usize>,
182 },
183
184 /// Memory allocation failed
185 ///
186 /// This variant indicates that a memory allocation request failed during
187 /// serialization or deserialization. It provides details about the requested
188 /// size and available memory (if known).
189 ///
190 /// # Fields
191 ///
192 /// * `requested_size` - Number of bytes that were requested
193 /// * `available_memory` - Number of bytes available (if known)
194 ///
195 /// # Common Causes
196 ///
197 /// - Insufficient system memory
198 /// - Memory fragmentation
199 /// - Resource limits exceeded
200 /// - Large tensor allocations
201 /// - Memory pool exhaustion
202 AllocationFailed {
203 /// Number of bytes that were requested
204 requested_size: usize,
205 /// Number of bytes available (if known)
206 available_memory: Option<usize>,
207 },
208
209 /// Generic error with custom message
210 ///
211 /// This variant provides a catch-all for generic serialization errors that
212 /// don't fit into the other specific categories. It allows for custom error
213 /// messages while maintaining the unified error interface.
214 ///
215 /// # Common Uses
216 ///
217 /// - Custom validation logic
218 /// - Business rule violations
219 /// - Unsupported operations
220 /// - Configuration errors
221 /// - Third-party integration issues
222 Custom(String),
223
224 // Compatibility variants - these will be removed after refactoring
225 /// @deprecated Use Json(JsonError::Format) instead
226 ///
227 /// This variant is deprecated and will be removed in a future version.
228 /// Use `Json(JsonError::Format)` instead for JSON format errors.
229 ///
230 /// # Migration
231 ///
232 /// Replace usage with the new format-specific error variants.
233 JsonFormat {
234 message: String,
235 line: Option<usize>,
236 column: Option<usize>,
237 },
238
239 /// @deprecated Use Binary(BinaryError::Format) instead
240 ///
241 /// This variant is deprecated and will be removed in a future version.
242 /// Use `Binary(BinaryError::Format)` instead for binary format errors.
243 ///
244 /// # Migration
245 ///
246 /// Replace usage with the new format-specific error variants.
247 BinaryFormat {
248 message: String,
249 position: Option<usize>,
250 },
251
252 /// @deprecated Use Binary(BinaryError::VersionMismatch) instead
253 ///
254 /// This variant is deprecated and will be removed in a future version.
255 /// Use `Binary(BinaryError::VersionMismatch)` instead for version mismatch errors.
256 ///
257 /// # Migration
258 ///
259 /// Replace usage with the new format-specific error variants.
260 VersionMismatch { expected: u32, found: u32 },
261
262 /// @deprecated Use Binary(BinaryError::InvalidMagic) instead
263 ///
264 /// This variant is deprecated and will be removed in a future version.
265 /// Use `Binary(BinaryError::InvalidMagic)` instead for invalid magic number errors.
266 ///
267 /// # Migration
268 ///
269 /// Replace usage with the new format-specific error variants.
270 InvalidMagic { expected: u32, found: u32 },
271}
272
273impl fmt::Display for SerializationError {
274 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
275 match self {
276 SerializationError::Io(err) => {
277 write!(f, "I/O error during serialization: {}", err)
278 }
279 SerializationError::Json(err) => {
280 write!(f, "JSON error: {}", err)
281 }
282 SerializationError::Binary(err) => {
283 write!(f, "Binary error: {}", err)
284 }
285 SerializationError::ValidationFailed { field, message } => {
286 write!(f, "Validation failed for field '{}': {}", field, message)
287 }
288 SerializationError::ShapeMismatch {
289 expected_dims,
290 found_dims,
291 } => {
292 write!(
293 f,
294 "Shape mismatch: expected {:?}, found {:?}",
295 expected_dims, found_dims
296 )
297 }
298 SerializationError::AllocationFailed {
299 requested_size,
300 available_memory,
301 } => match available_memory {
302 Some(available) => {
303 write!(
304 f,
305 "Memory allocation failed: requested {} bytes, {} bytes available",
306 requested_size, available
307 )
308 }
309 None => {
310 write!(
311 f,
312 "Memory allocation failed: requested {} bytes",
313 requested_size
314 )
315 }
316 },
317 SerializationError::Custom(message) => {
318 write!(f, "Serialization error: {}", message)
319 }
320 // Compatibility variants
321 SerializationError::JsonFormat {
322 message,
323 line,
324 column,
325 } => match (line, column) {
326 (Some(l), Some(c)) => {
327 write!(
328 f,
329 "JSON format error at line {}, column {}: {}",
330 l, c, message
331 )
332 }
333 (Some(l), None) => {
334 write!(f, "JSON format error at line {}: {}", l, message)
335 }
336 _ => {
337 write!(f, "JSON format error: {}", message)
338 }
339 },
340 SerializationError::BinaryFormat { message, position } => match position {
341 Some(pos) => {
342 write!(f, "Binary format error at position {}: {}", pos, message)
343 }
344 None => {
345 write!(f, "Binary format error: {}", message)
346 }
347 },
348 SerializationError::VersionMismatch { expected, found } => {
349 write!(
350 f,
351 "Version mismatch: expected {}, found {}",
352 expected, found
353 )
354 }
355 SerializationError::InvalidMagic { expected, found } => {
356 write!(
357 f,
358 "Invalid magic number: expected 0x{:08X}, found 0x{:08X}",
359 expected, found
360 )
361 }
362 }
363 }
364}
365
366impl std::error::Error for SerializationError {
367 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
368 match self {
369 SerializationError::Io(err) => Some(err),
370 SerializationError::Json(err) => Some(err),
371 SerializationError::Binary(err) => Some(err),
372 _ => None,
373 }
374 }
375}
376
377impl From<io::Error> for SerializationError {
378 /// Convert an I/O error to a SerializationError
379 ///
380 /// This implementation allows I/O errors to be automatically converted
381 /// to SerializationError instances, enabling seamless error propagation
382 /// in serialization operations.
383 ///
384
385 fn from(err: io::Error) -> Self {
386 SerializationError::Io(err)
387 }
388}
389
390impl From<crate::serialization::json::JsonError> for SerializationError {
391 /// Convert a JSON error to a SerializationError
392 ///
393 /// This implementation allows JSON-specific errors to be automatically
394 /// converted to SerializationError instances, maintaining error context
395 /// while providing a unified error interface.
396 ///
397
398 fn from(err: crate::serialization::json::JsonError) -> Self {
399 SerializationError::Json(err)
400 }
401}
402
403impl From<crate::serialization::binary::BinaryError> for SerializationError {
404 /// Convert a binary error to a SerializationError
405 ///
406 /// This implementation allows binary-specific errors to be automatically
407 /// converted to SerializationError instances, maintaining error context
408 /// while providing a unified error interface.
409 ///
410
411 fn from(err: crate::serialization::binary::BinaryError) -> Self {
412 SerializationError::Binary(err)
413 }
414}
415
416impl From<String> for SerializationError {
417 /// Convert a String to a SerializationError
418 ///
419 /// This implementation allows String values to be automatically converted
420 /// to SerializationError::Custom instances, providing a convenient way
421 /// to create custom error messages.
422 ///
423
424 fn from(message: String) -> Self {
425 SerializationError::Custom(message)
426 }
427}
428
429impl From<&str> for SerializationError {
430 /// Convert a string slice to a SerializationError
431 ///
432 /// This implementation allows string slices to be automatically converted
433 /// to SerializationError::Custom instances, providing a convenient way
434 /// to create custom error messages from string literals.
435 ///
436
437 fn from(message: &str) -> Self {
438 SerializationError::Custom(message.to_string())
439 }
440}
441
442impl SerializationError {
443 /// Create a JSON format error
444 ///
445 /// This method provides a convenient way to create JSON format errors
446 /// with optional line and column information for debugging.
447 ///
448 /// # Arguments
449 ///
450 /// * `message` - Human-readable error message describing the JSON format problem
451 /// * `line` - Line number where the error occurred (1-based, if available)
452 /// * `column` - Column number where the error occurred (1-based, if available)
453 ///
454 /// # Returns
455 ///
456 /// A SerializationError::Json variant with the specified format error
457 ///
458
459 pub fn json_format(message: String, line: Option<usize>, column: Option<usize>) -> Self {
460 SerializationError::Json(crate::serialization::json::JsonError::Format {
461 message,
462 line,
463 column,
464 })
465 }
466
467 /// Create a binary format error
468 ///
469 /// This method provides a convenient way to create binary format errors
470 /// with optional position information for debugging.
471 ///
472 /// # Arguments
473 ///
474 /// * `message` - Human-readable error message describing the binary format problem
475 /// * `position` - Byte position where the error occurred (if available)
476 ///
477 /// # Returns
478 ///
479 /// A SerializationError::Binary variant with the specified format error
480 ///
481
482 pub fn binary_format(message: String, position: Option<usize>) -> Self {
483 SerializationError::Binary(crate::serialization::binary::BinaryError::Format {
484 message,
485 position,
486 })
487 }
488
489 /// Create a binary version mismatch error
490 ///
491 /// This method provides a convenient way to create binary version mismatch
492 /// errors when the expected and actual format versions don't match.
493 ///
494 /// # Arguments
495 ///
496 /// * `expected` - Expected format version that the deserializer supports
497 /// * `found` - Actual format version found in the binary data
498 ///
499 /// # Returns
500 ///
501 /// A SerializationError::Binary variant with the specified version mismatch error
502 ///
503
504 pub fn binary_version_mismatch(expected: u32, found: u32) -> Self {
505 SerializationError::Binary(crate::serialization::binary::BinaryError::VersionMismatch {
506 expected,
507 found,
508 })
509 }
510
511 /// Create a binary invalid magic error
512 ///
513 /// This method provides a convenient way to create binary invalid magic
514 /// errors when the binary data doesn't start with the expected magic number.
515 ///
516 /// # Arguments
517 ///
518 /// * `expected` - Expected magic number value for the binary format
519 /// * `found` - Actual magic number found at the beginning of the data
520 ///
521 /// # Returns
522 ///
523 /// A SerializationError::Binary variant with the specified invalid magic error
524 ///
525
526 pub fn binary_invalid_magic(expected: u32, found: u32) -> Self {
527 SerializationError::Binary(crate::serialization::binary::BinaryError::InvalidMagic {
528 expected,
529 found,
530 })
531 }
532}