Skip to main content

memscope_rs/error/
conversions.rs

1//! Error type conversions to MemScopeError
2//!
3//! Provides conversions from various module-specific error types
4//! to the unified MemScopeError type for centralized error handling.
5
6use crate::core::error::{MemScopeError, MemoryOperation, SystemErrorType};
7
8use super::error_manager::IntoMemScopeError;
9
10// Implement IntoMemScopeError for AsyncError
11impl IntoMemScopeError for crate::capture::backends::async_types::AsyncError {
12    fn into_memscope_error(self, module: &str) -> MemScopeError {
13        use crate::capture::backends::async_types::AsyncError;
14
15        match self {
16            AsyncError::Initialization {
17                component,
18                message,
19                recoverable: _,
20            } => MemScopeError::config(component, message.as_ref()),
21            AsyncError::TaskTracking {
22                operation,
23                message,
24                task_id,
25            } => {
26                let context = task_id.map(|id| format!("task_id: {}", id));
27                let operation_str = format!("{:?}", operation);
28                MemScopeError::memory_with_context(
29                    MemoryOperation::Tracking,
30                    message.as_ref(),
31                    format!(
32                        "{}: {} - {:?}",
33                        module,
34                        operation_str,
35                        context.unwrap_or_default()
36                    ),
37                )
38            }
39            AsyncError::AllocationTracking {
40                event_type,
41                message,
42                allocation_size,
43            } => {
44                let context = allocation_size.map(|size| format!("size: {} bytes", size));
45                let event_type_str = format!("{:?}", event_type);
46                MemScopeError::memory_with_context(
47                    MemoryOperation::Allocation,
48                    message.as_ref(),
49                    format!(
50                        "{}: {} - {:?}",
51                        module,
52                        event_type_str,
53                        context.unwrap_or_default()
54                    ),
55                )
56            }
57            AsyncError::System {
58                operation: _,
59                message,
60            } => MemScopeError::system(
61                SystemErrorType::Threading,
62                format!("{}: {}", module, message),
63            ),
64        }
65    }
66}
67
68// Implement IntoMemScopeError for ExportError
69impl IntoMemScopeError for crate::render_engine::export::ExportError {
70    fn into_memscope_error(self, module: &str) -> MemScopeError {
71        use crate::render_engine::export::ExportError;
72
73        match self {
74            ExportError::Io(err) => MemScopeError::system_with_source(
75                SystemErrorType::Io,
76                format!("{}: IO error", module),
77                err,
78            ),
79            ExportError::Json(err) => MemScopeError::system_with_source(
80                SystemErrorType::Serialization,
81                format!("{}: JSON error", module),
82                err,
83            ),
84            ExportError::ExportFailed(msg) => {
85                MemScopeError::export_partial("general", format!("{}: {}", module, msg))
86            }
87        }
88    }
89}
90
91// Implement IntoMemScopeError for TrackingError (capture::types)
92impl IntoMemScopeError for crate::capture::types::TrackingError {
93    fn into_memscope_error(self, module: &str) -> MemScopeError {
94        use crate::capture::types::TrackingError;
95
96        match self {
97            TrackingError::AllocationFailed(msg) => MemScopeError::memory_with_context(
98                MemoryOperation::Allocation,
99                msg.as_str(),
100                module,
101            ),
102            TrackingError::DeallocationFailed(msg) => MemScopeError::memory_with_context(
103                MemoryOperation::Deallocation,
104                msg.as_str(),
105                module,
106            ),
107            TrackingError::TrackingDisabled => {
108                MemScopeError::config(module, "Memory tracking is disabled")
109            }
110            TrackingError::InvalidPointer(msg) => MemScopeError::memory_with_context(
111                MemoryOperation::Validation,
112                msg.as_str(),
113                module,
114            ),
115            TrackingError::SerializationError(msg) => MemScopeError::system(
116                SystemErrorType::Serialization,
117                format!("{}: {}", module, msg),
118            ),
119            TrackingError::VisualizationError(msg) => {
120                MemScopeError::export("visualization", format!("{}: {}", module, msg))
121            }
122            TrackingError::ThreadSafetyError(msg) => {
123                MemScopeError::system(SystemErrorType::Threading, format!("{}: {}", module, msg))
124            }
125            TrackingError::ConfigurationError(msg) => MemScopeError::config(module, msg.as_str()),
126            TrackingError::AnalysisError(msg) => MemScopeError::analysis(module, msg.as_str()),
127            TrackingError::ExportError(msg) => {
128                MemScopeError::export("general", format!("{}: {}", module, msg))
129            }
130            TrackingError::MemoryCorruption(msg) => MemScopeError::memory_with_context(
131                MemoryOperation::Validation,
132                msg.as_str(),
133                module,
134            ),
135            TrackingError::UnsafeOperationDetected(msg) => {
136                MemScopeError::analysis("unsafe", format!("{}: {}", module, msg))
137            }
138            TrackingError::FFIError(msg) => {
139                MemScopeError::analysis("ffi", format!("{}: {}", module, msg))
140            }
141            TrackingError::ScopeError(msg) => {
142                MemScopeError::memory_with_context(MemoryOperation::Tracking, msg.as_str(), module)
143            }
144            TrackingError::BorrowCheckError(msg) => {
145                MemScopeError::analysis("borrow", format!("{}: {}", module, msg))
146            }
147            TrackingError::LifetimeError(msg) => {
148                MemScopeError::analysis("lifetime", format!("{}: {}", module, msg))
149            }
150            TrackingError::TypeInferenceError(msg) => {
151                MemScopeError::analysis("type", format!("{}: {}", module, msg))
152            }
153            TrackingError::PerformanceError(msg) => {
154                MemScopeError::system(SystemErrorType::Io, format!("{}: {}", module, msg))
155            }
156            TrackingError::ResourceExhausted(msg) => {
157                MemScopeError::system(SystemErrorType::Io, format!("{}: {}", module, msg))
158            }
159            TrackingError::InternalError(msg) => {
160                MemScopeError::internal(format!("{}: {}", module, msg))
161            }
162            TrackingError::IoError(msg) => {
163                MemScopeError::system(SystemErrorType::Io, format!("{}: {}", module, msg))
164            }
165            TrackingError::LockError(msg) => {
166                MemScopeError::system(SystemErrorType::Locking, format!("{}: {}", module, msg))
167            }
168            TrackingError::ChannelError(msg) => {
169                MemScopeError::system(SystemErrorType::Channel, format!("{}: {}", module, msg))
170            }
171            TrackingError::ThreadError(msg) => {
172                MemScopeError::system(SystemErrorType::Threading, format!("{}: {}", module, msg))
173            }
174            TrackingError::InitializationError(msg) => MemScopeError::config(module, msg.as_str()),
175            TrackingError::NotImplemented(msg) => {
176                MemScopeError::internal(format!("{}: {}", module, msg))
177            }
178            TrackingError::ValidationError(msg) => MemScopeError::memory_with_context(
179                MemoryOperation::Validation,
180                msg.as_str(),
181                module,
182            ),
183            TrackingError::InvalidOperation(msg) => {
184                MemScopeError::memory_with_context(MemoryOperation::Tracking, msg.as_str(), module)
185            }
186            TrackingError::LockContention(msg) => {
187                MemScopeError::system(SystemErrorType::Locking, format!("{}: {}", module, msg))
188            }
189            TrackingError::DataError(msg) => {
190                MemScopeError::memory_with_context(MemoryOperation::Tracking, msg.as_str(), module)
191            }
192        }
193    }
194}
195
196// Implement IntoMemScopeError for TrackingError (core::types)
197impl IntoMemScopeError for crate::core::types::TrackingError {
198    fn into_memscope_error(self, module: &str) -> MemScopeError {
199        use crate::core::types::TrackingError;
200
201        match self {
202            TrackingError::AllocationFailed(msg) => MemScopeError::memory_with_context(
203                MemoryOperation::Allocation,
204                msg.as_str(),
205                module,
206            ),
207            TrackingError::DeallocationFailed(msg) => MemScopeError::memory_with_context(
208                MemoryOperation::Deallocation,
209                msg.as_str(),
210                module,
211            ),
212            TrackingError::TrackingDisabled => {
213                MemScopeError::config(module, "Memory tracking is disabled")
214            }
215            TrackingError::InvalidPointer(msg) => MemScopeError::memory_with_context(
216                MemoryOperation::Validation,
217                msg.as_str(),
218                module,
219            ),
220            TrackingError::SerializationError(msg) => MemScopeError::system(
221                SystemErrorType::Serialization,
222                format!("{}: {}", module, msg),
223            ),
224            TrackingError::VisualizationError(msg) => {
225                MemScopeError::export("visualization", format!("{}: {}", module, msg))
226            }
227            TrackingError::ThreadSafetyError(msg) => {
228                MemScopeError::system(SystemErrorType::Threading, format!("{}: {}", module, msg))
229            }
230            TrackingError::ConfigurationError(msg) => MemScopeError::config(module, msg.as_str()),
231            TrackingError::AnalysisError(msg) => MemScopeError::analysis(module, msg.as_str()),
232            TrackingError::ExportError(msg) => {
233                MemScopeError::export("general", format!("{}: {}", module, msg))
234            }
235            TrackingError::MemoryCorruption(msg) => MemScopeError::memory_with_context(
236                MemoryOperation::Validation,
237                msg.as_str(),
238                module,
239            ),
240            TrackingError::UnsafeOperationDetected(msg) => {
241                MemScopeError::analysis("unsafe", format!("{}: {}", module, msg))
242            }
243            TrackingError::FFIError(msg) => {
244                MemScopeError::analysis("ffi", format!("{}: {}", module, msg))
245            }
246            TrackingError::ScopeError(msg) => {
247                MemScopeError::memory_with_context(MemoryOperation::Tracking, msg.as_str(), module)
248            }
249            TrackingError::BorrowCheckError(msg) => {
250                MemScopeError::analysis("borrow", format!("{}: {}", module, msg))
251            }
252            TrackingError::LifetimeError(msg) => {
253                MemScopeError::analysis("lifetime", format!("{}: {}", module, msg))
254            }
255            TrackingError::TypeInferenceError(msg) => {
256                MemScopeError::analysis("type", format!("{}: {}", module, msg))
257            }
258            TrackingError::PerformanceError(msg) => {
259                MemScopeError::system(SystemErrorType::Io, format!("{}: {}", module, msg))
260            }
261            TrackingError::ResourceExhausted(msg) => {
262                MemScopeError::system(SystemErrorType::Io, format!("{}: {}", module, msg))
263            }
264            TrackingError::InternalError(msg) => {
265                MemScopeError::internal(format!("{}: {}", module, msg))
266            }
267            TrackingError::IoError(msg) => {
268                MemScopeError::system(SystemErrorType::Io, format!("{}: {}", module, msg))
269            }
270            TrackingError::LockError(msg) => {
271                MemScopeError::system(SystemErrorType::Locking, format!("{}: {}", module, msg))
272            }
273            TrackingError::ChannelError(msg) => {
274                MemScopeError::system(SystemErrorType::Channel, format!("{}: {}", module, msg))
275            }
276            TrackingError::ThreadError(msg) => {
277                MemScopeError::system(SystemErrorType::Threading, format!("{}: {}", module, msg))
278            }
279            TrackingError::InitializationError(msg) => MemScopeError::config(module, msg.as_str()),
280            TrackingError::NotImplemented(msg) => {
281                MemScopeError::internal(format!("{}: {}", module, msg))
282            }
283            TrackingError::ValidationError(msg) => MemScopeError::memory_with_context(
284                MemoryOperation::Validation,
285                msg.as_str(),
286                module,
287            ),
288            TrackingError::InvalidOperation(msg) => {
289                MemScopeError::memory_with_context(MemoryOperation::Tracking, msg.as_str(), module)
290            }
291            TrackingError::LockContention(msg) => {
292                MemScopeError::system(SystemErrorType::Locking, format!("{}: {}", module, msg))
293            }
294            TrackingError::DataError(msg) => {
295                MemScopeError::memory_with_context(MemoryOperation::Tracking, msg.as_str(), module)
296            }
297        }
298    }
299}
300
301#[cfg(test)]
302mod tests {
303    use super::*;
304
305    #[test]
306    fn test_async_error_conversion() {
307        use crate::capture::backends::async_types::AsyncError;
308
309        let error = AsyncError::Initialization {
310            component: "test".into(),
311            message: "failed".into(),
312            recoverable: false,
313        };
314        let memscope_error = error.into_memscope_error("test_module");
315
316        assert!(matches!(
317            memscope_error,
318            MemScopeError::Configuration { .. }
319        ));
320    }
321
322    #[test]
323    fn test_tracking_error_conversion() {
324        use crate::capture::types::TrackingError;
325
326        let error = TrackingError::AllocationFailed("test failed".to_string());
327        let memscope_error = error.into_memscope_error("test_module");
328
329        assert!(matches!(memscope_error, MemScopeError::Memory { .. }));
330    }
331}