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