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] bincode::error::EncodeError),
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    /// PyTorch/tch error
111    #[cfg(feature = "auto-feature-engineering")]
112    #[error("PyTorch error: {0}")]
113    TchError(#[from] tch::TchError),
114
115    /// Other error
116    #[error("Error: {0}")]
117    Other(String),
118}
119
120/// Result type for data transformation operations
121pub type Result<T> = std::result::Result<T, TransformError>;
122
123/// Context trait for adding context to errors
124pub trait ErrorContext<T> {
125    /// Add context to an error
126    fn context(self, msg: &str) -> Result<T>;
127
128    /// Add context with a format string
129    fn with_context<F>(self, f: F) -> Result<T>
130    where
131        F: FnOnce() -> String;
132}
133
134impl<T> ErrorContext<T> for Result<T> {
135    fn context(self, msg: &str) -> Result<T> {
136        self.map_err(|e| TransformError::Other(format!("{msg}: {e}")))
137    }
138
139    fn with_context<F>(self, f: F) -> Result<T>
140    where
141        F: FnOnce() -> String,
142    {
143        self.map_err(|e| TransformError::Other(format!("{}: {e}", f())))
144    }
145}
146
147/// Error kind for categorizing errors
148#[derive(Debug, Clone, PartialEq, Eq)]
149pub enum ErrorKind {
150    /// Input validation errors
151    Validation,
152    /// Computation errors
153    Computation,
154    /// Configuration errors
155    Configuration,
156    /// Resource errors (memory, GPU, etc.)
157    Resource,
158    /// External errors (IO, network, etc.)
159    External,
160    /// Internal errors (bugs, not implemented, etc.)
161    Internal,
162}
163
164impl TransformError {
165    /// Get the error kind
166    pub fn kind(&self) -> ErrorKind {
167        match self {
168            TransformError::InvalidInput(_)
169            | TransformError::DataValidationError(_)
170            | TransformError::ConfigurationError(_) => ErrorKind::Validation,
171
172            TransformError::ComputationError(_)
173            | TransformError::TransformationError(_)
174            | TransformError::ConvergenceError(_)
175            | TransformError::SimdError(_) => ErrorKind::Computation,
176
177            TransformError::MemoryError(_)
178            | TransformError::GpuError(_)
179            | TransformError::TimeoutError(_) => ErrorKind::Resource,
180
181            TransformError::IoError(_)
182            | TransformError::DistributedError(_)
183            | TransformError::StreamingError(_)
184            | TransformError::MonitoringError(_) => ErrorKind::External,
185
186            TransformError::NotImplemented(_)
187            | TransformError::NotFitted(_)
188            | TransformError::FeatureNotEnabled(_)
189            | TransformError::Other(_) => ErrorKind::Internal,
190
191            TransformError::CoreError(_)
192            | TransformError::LinalgError(_)
193            | TransformError::FFTError(_) => ErrorKind::External,
194
195            TransformError::ParallelError(_)
196            | TransformError::CrossValidationError(_)
197            | TransformError::ParseError(_) => ErrorKind::Computation,
198
199            #[cfg(feature = "monitoring")]
200            TransformError::PrometheusError(_) => ErrorKind::External,
201
202            #[cfg(feature = "distributed")]
203            TransformError::SerializationError(_) => ErrorKind::External,
204
205            #[cfg(feature = "auto-feature-engineering")]
206            TransformError::TchError(_) => ErrorKind::Computation,
207        }
208    }
209
210    /// Check if the error is recoverable
211    pub fn is_recoverable(&self) -> bool {
212        match self.kind() {
213            ErrorKind::Validation | ErrorKind::Configuration => false,
214            ErrorKind::Resource | ErrorKind::External => true,
215            ErrorKind::Computation => true, // May be recoverable with different params
216            ErrorKind::Internal => false,
217        }
218    }
219
220    /// Check if the error should trigger a retry
221    pub fn should_retry(&self) -> bool {
222        matches!(
223            self,
224            TransformError::TimeoutError(_)
225                | TransformError::MemoryError(_)
226                | TransformError::DistributedError(_)
227                | TransformError::StreamingError(_)
228                | TransformError::ParallelError(_)
229                | TransformError::IoError(_)
230        )
231    }
232
233    /// Get user-friendly error message
234    pub fn user_message(&self) -> String {
235        match self {
236            TransformError::InvalidInput(_) => "Invalid input data provided".to_string(),
237            TransformError::NotFitted(_) => "Model must be fitted before use".to_string(),
238            TransformError::MemoryError(_) => "Insufficient memory for operation".to_string(),
239            TransformError::TimeoutError(_) => "Operation timed out".to_string(),
240            TransformError::FeatureNotEnabled(_) => "Required feature is not enabled".to_string(),
241            _ => "An error occurred during transformation".to_string(),
242        }
243    }
244}