Skip to main content

scirs2_transform/
error.rs

1//! Error types for the data transformation module
2
3use thiserror::Error;
4
5/// Error type for data transformation operations
6#[derive(Error, Debug)]
7pub enum TransformError {
8    /// Invalid input data
9    #[error("Invalid input: {0}")]
10    InvalidInput(String),
11
12    /// Transformation error
13    #[error("Transformation error: {0}")]
14    TransformationError(String),
15
16    /// Core error
17    #[error("Core error: {0}")]
18    CoreError(#[from] scirs2_core::error::CoreError),
19
20    /// Linear algebra error
21    #[error("Linear algebra error: {0}")]
22    LinalgError(#[from] scirs2_linalg::error::LinalgError),
23
24    /// FFT error
25    #[error("FFT error: {0}")]
26    FFTError(#[from] scirs2_fft::error::FFTError),
27
28    /// IO error
29    #[error("IO error: {0}")]
30    IoError(#[from] std::io::Error),
31
32    /// Computation error
33    #[error("Computation error: {0}")]
34    ComputationError(String),
35
36    /// Model not fitted error
37    #[error("Model not fitted: {0}")]
38    NotFitted(String),
39
40    /// Feature not enabled error
41    #[error("Feature not enabled: {0}")]
42    FeatureNotEnabled(String),
43
44    /// GPU error
45    #[error("GPU error: {0}")]
46    GpuError(String),
47
48    /// Distributed processing error
49    #[error("Distributed processing error: {0}")]
50    DistributedError(String),
51
52    /// Monitoring error
53    #[error("Monitoring error: {0}")]
54    MonitoringError(String),
55
56    /// Memory allocation error
57    #[error("Memory error: {0}")]
58    MemoryError(String),
59
60    /// Convergence failure in iterative algorithms
61    #[error("Convergence error: {0}")]
62    ConvergenceError(String),
63
64    /// Data quality or validation error
65    #[error("Data validation error: {0}")]
66    DataValidationError(String),
67
68    /// Threading or parallel processing error
69    #[error("Parallel processing error: {0}")]
70    ParallelError(String),
71
72    /// Configuration validation error
73    #[error("Configuration error: {0}")]
74    ConfigurationError(String),
75
76    /// Timeout error for long-running operations
77    #[error("Timeout error: {0}")]
78    TimeoutError(String),
79
80    /// SIMD operation error
81    #[error("SIMD error: {0}")]
82    SimdError(String),
83
84    /// Streaming data pipeline error
85    #[error("Streaming error: {0}")]
86    StreamingError(String),
87
88    /// Cross-validation error
89    #[error("Cross-validation error: {0}")]
90    CrossValidationError(String),
91
92    /// Prometheus error
93    #[cfg(feature = "monitoring")]
94    #[error("Prometheus error: {0}")]
95    PrometheusError(#[from] prometheus::Error),
96
97    /// Serialization error
98    #[cfg(feature = "distributed")]
99    #[error("Serialization error: {0}")]
100    SerializationError(#[from] oxicode::Error),
101
102    /// Not implemented error
103    #[error("Not implemented: {0}")]
104    NotImplemented(String),
105
106    /// Parse error
107    #[error("Parse error: {0}")]
108    ParseError(String),
109
110    /// Other error
111    #[error("Error: {0}")]
112    Other(String),
113}
114
115/// Result type for data transformation operations
116pub type Result<T> = std::result::Result<T, TransformError>;
117
118/// Context trait for adding context to errors
119pub trait ErrorContext<T> {
120    /// Add context to an error
121    fn context(self, msg: &str) -> Result<T>;
122
123    /// Add context with a format string
124    fn with_context<F>(self, f: F) -> Result<T>
125    where
126        F: FnOnce() -> String;
127}
128
129impl<T> ErrorContext<T> for Result<T> {
130    fn context(self, msg: &str) -> Result<T> {
131        self.map_err(|e| TransformError::Other(format!("{msg}: {e}")))
132    }
133
134    fn with_context<F>(self, f: F) -> Result<T>
135    where
136        F: FnOnce() -> String,
137    {
138        self.map_err(|e| TransformError::Other(format!("{}: {e}", f())))
139    }
140}
141
142/// Error kind for categorizing errors
143#[derive(Debug, Clone, PartialEq, Eq)]
144pub enum ErrorKind {
145    /// Input validation errors
146    Validation,
147    /// Computation errors
148    Computation,
149    /// Configuration errors
150    Configuration,
151    /// Resource errors (memory, GPU, etc.)
152    Resource,
153    /// External errors (IO, network, etc.)
154    External,
155    /// Internal errors (bugs, not implemented, etc.)
156    Internal,
157}
158
159impl TransformError {
160    /// Get the error kind
161    pub fn kind(&self) -> ErrorKind {
162        match self {
163            TransformError::InvalidInput(_)
164            | TransformError::DataValidationError(_)
165            | TransformError::ConfigurationError(_) => ErrorKind::Validation,
166
167            TransformError::ComputationError(_)
168            | TransformError::TransformationError(_)
169            | TransformError::ConvergenceError(_)
170            | TransformError::SimdError(_) => ErrorKind::Computation,
171
172            TransformError::MemoryError(_)
173            | TransformError::GpuError(_)
174            | TransformError::TimeoutError(_) => ErrorKind::Resource,
175
176            TransformError::IoError(_)
177            | TransformError::DistributedError(_)
178            | TransformError::StreamingError(_)
179            | TransformError::MonitoringError(_) => ErrorKind::External,
180
181            TransformError::NotImplemented(_)
182            | TransformError::NotFitted(_)
183            | TransformError::FeatureNotEnabled(_)
184            | TransformError::Other(_) => ErrorKind::Internal,
185
186            TransformError::CoreError(_)
187            | TransformError::LinalgError(_)
188            | TransformError::FFTError(_) => ErrorKind::External,
189
190            TransformError::ParallelError(_)
191            | TransformError::CrossValidationError(_)
192            | TransformError::ParseError(_) => ErrorKind::Computation,
193
194            #[cfg(feature = "monitoring")]
195            TransformError::PrometheusError(_) => ErrorKind::External,
196
197            #[cfg(feature = "distributed")]
198            TransformError::SerializationError(_) => ErrorKind::External,
199        }
200    }
201
202    /// Check if the error is recoverable
203    pub fn is_recoverable(&self) -> bool {
204        match self.kind() {
205            ErrorKind::Validation | ErrorKind::Configuration => false,
206            ErrorKind::Resource | ErrorKind::External => true,
207            ErrorKind::Computation => true, // May be recoverable with different params
208            ErrorKind::Internal => false,
209        }
210    }
211
212    /// Check if the error should trigger a retry
213    pub fn should_retry(&self) -> bool {
214        matches!(
215            self,
216            TransformError::TimeoutError(_)
217                | TransformError::MemoryError(_)
218                | TransformError::DistributedError(_)
219                | TransformError::StreamingError(_)
220                | TransformError::ParallelError(_)
221                | TransformError::IoError(_)
222        )
223    }
224
225    /// Get user-friendly error message
226    pub fn user_message(&self) -> String {
227        match self {
228            TransformError::InvalidInput(_) => "Invalid input data provided".to_string(),
229            TransformError::NotFitted(_) => "Model must be fitted before use".to_string(),
230            TransformError::MemoryError(_) => "Insufficient memory for operation".to_string(),
231            TransformError::TimeoutError(_) => "Operation timed out".to_string(),
232            TransformError::FeatureNotEnabled(_) => "Required feature is not enabled".to_string(),
233            _ => "An error occurred during transformation".to_string(),
234        }
235    }
236}