Skip to main content

ferrum_types/
errors.rs

1//! Error types for Ferrum inference framework
2
3use serde::{Deserialize, Serialize};
4use thiserror::Error;
5
6/// Main error type for Ferrum operations
7#[derive(Debug, Error, Clone, Serialize, Deserialize)]
8pub enum FerrumError {
9    /// Configuration errors
10    #[error("Configuration error: {message}")]
11    Config { message: String },
12
13    /// Model loading/initialization errors
14    #[error("Model error: {message}")]
15    Model { message: String },
16
17    /// Tokenizer errors
18    #[error("Tokenizer error: {message}")]
19    Tokenizer { message: String },
20
21    /// Backend/runtime errors
22    #[error("Backend error: {message}")]
23    Backend { message: String },
24
25    /// Device/memory errors
26    #[error("Device error: {message}")]
27    Device { message: String },
28
29    /// Scheduling/queue errors
30    #[error("Scheduler error: {message}")]
31    Scheduler { message: String },
32
33    /// Request validation errors
34    #[error("Request validation error: {message}")]
35    RequestValidation { message: String },
36
37    /// Resource exhaustion errors
38    #[error("Resource exhausted: {message}")]
39    ResourceExhausted { message: String },
40
41    /// Timeout errors
42    #[error("Operation timed out: {message}")]
43    Timeout { message: String },
44
45    /// Authentication/authorization errors
46    #[error("Authentication error: {message}")]
47    Auth { message: String },
48
49    /// Rate limiting errors
50    #[error("Rate limit exceeded: {message}")]
51    RateLimit { message: String },
52
53    /// I/O errors
54    #[error("I/O error: {message}")]
55    IO { message: String },
56
57    /// Serialization/deserialization errors
58    #[error("Serialization error: {message}")]
59    Serialization { message: String },
60
61    /// Network errors
62    #[error("Network error: {message}")]
63    Network { message: String },
64
65    /// Internal errors (should not happen in normal operation)
66    #[error("Internal error: {message}")]
67    Internal { message: String },
68
69    /// Request was cancelled
70    #[error("Request cancelled: {message}")]
71    Cancelled { message: String },
72
73    /// Not found errors
74    #[error("Not found: {message}")]
75    NotFound { message: String },
76
77    /// Already exists errors
78    #[error("Already exists: {message}")]
79    AlreadyExists { message: String },
80
81    /// Permission denied errors
82    #[error("Permission denied: {message}")]
83    PermissionDenied { message: String },
84
85    /// Unsupported operation errors
86    #[error("Unsupported operation: {message}")]
87    Unsupported { message: String },
88
89    /// Invalid format errors (parsing, schema mismatches)
90    #[error("Invalid format: {message}")]
91    InvalidFormat { message: String },
92
93    /// Invalid parameters or configuration values
94    #[error("Invalid parameter: {message}")]
95    InvalidParameter { message: String },
96}
97
98impl FerrumError {
99    /// Create a configuration error
100    pub fn config(message: impl Into<String>) -> Self {
101        Self::Config {
102            message: message.into(),
103        }
104    }
105
106    /// Create a model error
107    pub fn model(message: impl Into<String>) -> Self {
108        Self::Model {
109            message: message.into(),
110        }
111    }
112
113    /// Create a tokenizer error
114    pub fn tokenizer(message: impl Into<String>) -> Self {
115        Self::Tokenizer {
116            message: message.into(),
117        }
118    }
119
120    /// Create a backend error
121    pub fn backend(message: impl Into<String>) -> Self {
122        Self::Backend {
123            message: message.into(),
124        }
125    }
126
127    /// Create a device error
128    pub fn device(message: impl Into<String>) -> Self {
129        Self::Device {
130            message: message.into(),
131        }
132    }
133
134    /// Create a scheduler error
135    pub fn scheduler(message: impl Into<String>) -> Self {
136        Self::Scheduler {
137            message: message.into(),
138        }
139    }
140
141    /// Create a request validation error
142    pub fn request_validation(message: impl Into<String>) -> Self {
143        Self::RequestValidation {
144            message: message.into(),
145        }
146    }
147
148    /// Create a resource exhausted error
149    pub fn resource_exhausted(message: impl Into<String>) -> Self {
150        Self::ResourceExhausted {
151            message: message.into(),
152        }
153    }
154
155    /// Create a timeout error
156    pub fn timeout(message: impl Into<String>) -> Self {
157        Self::Timeout {
158            message: message.into(),
159        }
160    }
161
162    /// Create an auth error
163    pub fn auth(message: impl Into<String>) -> Self {
164        Self::Auth {
165            message: message.into(),
166        }
167    }
168
169    /// Create a rate limit error
170    pub fn rate_limit(message: impl Into<String>) -> Self {
171        Self::RateLimit {
172            message: message.into(),
173        }
174    }
175
176    /// Create an I/O error
177    pub fn io(message: impl Into<String>) -> Self {
178        Self::IO {
179            message: message.into(),
180        }
181    }
182
183    /// Create a serialization error
184    pub fn serialization(message: impl Into<String>) -> Self {
185        Self::Serialization {
186            message: message.into(),
187        }
188    }
189
190    /// Create a network error
191    pub fn network(message: impl Into<String>) -> Self {
192        Self::Network {
193            message: message.into(),
194        }
195    }
196
197    /// Create an internal error
198    pub fn internal(message: impl Into<String>) -> Self {
199        Self::Internal {
200            message: message.into(),
201        }
202    }
203
204    /// Create a cancelled error
205    pub fn cancelled(message: impl Into<String>) -> Self {
206        Self::Cancelled {
207            message: message.into(),
208        }
209    }
210
211    /// Create a not found error
212    pub fn not_found(message: impl Into<String>) -> Self {
213        Self::NotFound {
214            message: message.into(),
215        }
216    }
217
218    /// Create an already exists error
219    pub fn already_exists(message: impl Into<String>) -> Self {
220        Self::AlreadyExists {
221            message: message.into(),
222        }
223    }
224
225    /// Create a permission denied error
226    pub fn permission_denied(message: impl Into<String>) -> Self {
227        Self::PermissionDenied {
228            message: message.into(),
229        }
230    }
231
232    /// Create an unsupported operation error
233    pub fn unsupported(message: impl Into<String>) -> Self {
234        Self::Unsupported {
235            message: message.into(),
236        }
237    }
238
239    /// Create an invalid format error (parsing/schema mismatch)
240    pub fn invalid_format(message: impl Into<String>) -> Self {
241        Self::InvalidFormat {
242            message: message.into(),
243        }
244    }
245
246    /// Create an invalid parameter error
247    pub fn invalid_parameter(message: impl Into<String>) -> Self {
248        Self::InvalidParameter {
249            message: message.into(),
250        }
251    }
252
253    // Alias methods for compatibility
254
255    /// Alias for io() - Create an I/O error from string
256    pub fn io_str(message: impl Into<String>) -> Self {
257        Self::io(message)
258    }
259
260    /// Alias for config() - Create a configuration error
261    pub fn configuration(message: impl Into<String>) -> Self {
262        Self::config(message)
263    }
264
265    /// Alias for serialization() - Create a deserialization error
266    pub fn deserialization(message: impl Into<String>) -> Self {
267        Self::serialization(message)
268    }
269
270    /// Alias for request_validation() - Create an invalid request error
271    pub fn invalid_request(message: impl Into<String>) -> Self {
272        Self::request_validation(message)
273    }
274
275    /// Check if this is a retryable error
276    pub fn is_retryable(&self) -> bool {
277        matches!(
278            self,
279            Self::ResourceExhausted { .. } | Self::Timeout { .. } | Self::Network { .. }
280        )
281    }
282
283    /// Check if this is a client error (4xx equivalent)
284    pub fn is_client_error(&self) -> bool {
285        matches!(
286            self,
287            Self::RequestValidation { .. }
288                | Self::Auth { .. }
289                | Self::RateLimit { .. }
290                | Self::NotFound { .. }
291                | Self::AlreadyExists { .. }
292                | Self::PermissionDenied { .. }
293                | Self::Unsupported { .. }
294        )
295    }
296
297    /// Check if this is a server error (5xx equivalent)
298    pub fn is_server_error(&self) -> bool {
299        matches!(
300            self,
301            Self::Model { .. }
302                | Self::Backend { .. }
303                | Self::Device { .. }
304                | Self::Scheduler { .. }
305                | Self::ResourceExhausted { .. }
306                | Self::Timeout { .. }
307                | Self::Internal { .. }
308        )
309    }
310}
311
312/// Conversion from std::io::Error
313impl From<std::io::Error> for FerrumError {
314    fn from(err: std::io::Error) -> Self {
315        Self::io(format!("{}", err))
316    }
317}
318
319/// Conversion from serde_json::Error
320impl From<serde_json::Error> for FerrumError {
321    fn from(err: serde_json::Error) -> Self {
322        Self::serialization(format!("{}", err))
323    }
324}