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}