1use crate::domain::Domain;
4use thiserror::Error;
5
6pub type Result<T> = std::result::Result<T, KernelError>;
8
9#[derive(Debug, Error)]
11pub enum KernelError {
12 #[error("Kernel not found: {0}")]
14 KernelNotFound(String),
15
16 #[error("Kernel already registered: {0}")]
18 KernelAlreadyRegistered(String),
19
20 #[error("Invalid state transition from {from} to {to}")]
22 InvalidStateTransition {
23 from: String,
25 to: String,
27 },
28
29 #[error("Kernel is not active: {0}")]
31 KernelNotActive(String),
32
33 #[error("Input validation failed: {0}")]
35 ValidationError(String),
36
37 #[error("Serialization error: {0}")]
39 SerializationError(String),
40
41 #[error("Deserialization error: {0}")]
43 DeserializationError(String),
44
45 #[error("Message queue full (capacity: {capacity})")]
47 QueueFull {
48 capacity: usize,
50 },
51
52 #[error("Message queue empty")]
54 QueueEmpty,
55
56 #[error("Message too large: {size} bytes (max: {max} bytes)")]
58 MessageTooLarge {
59 size: usize,
61 max: usize,
63 },
64
65 #[error("Timeout waiting for response after {0:?}")]
67 Timeout(std::time::Duration),
68
69 #[error("Kernel launch failed: {0}")]
71 LaunchFailed(String),
72
73 #[error("GPU compilation error: {0}")]
75 CompilationError(String),
76
77 #[error("GPU device error: {0}")]
79 DeviceError(String),
80
81 #[error("Backend not available: {0}")]
83 BackendNotAvailable(String),
84
85 #[error("License error: {0}")]
87 LicenseError(#[from] crate::license::LicenseError),
88
89 #[error("SLO violation: {0}")]
91 SLOViolation(String),
92
93 #[error("Domain not supported: {0}")]
95 DomainNotSupported(Domain),
96
97 #[error("Internal error: {0}")]
99 InternalError(String),
100
101 #[error("IO error: {0}")]
103 IoError(#[from] std::io::Error),
104
105 #[error("Configuration error: {0}")]
107 ConfigError(String),
108
109 #[error("Actor error: {0}")]
111 ActorError(String),
112
113 #[error("RingKernel error: {0}")]
115 RingKernelError(String),
116
117 #[error("K2K error: {0}")]
119 K2KError(String),
120
121 #[error("Unauthorized: {0}")]
124 Unauthorized(String),
125
126 #[error("Resource exhausted: {0}")]
128 ResourceExhausted(String),
129
130 #[error("Service unavailable: {0}")]
132 ServiceUnavailable(String),
133}
134
135impl KernelError {
136 #[must_use]
138 pub fn validation(msg: impl Into<String>) -> Self {
139 KernelError::ValidationError(msg.into())
140 }
141
142 #[must_use]
144 pub fn internal(msg: impl Into<String>) -> Self {
145 KernelError::InternalError(msg.into())
146 }
147
148 #[must_use]
150 pub fn not_found(id: impl Into<String>) -> Self {
151 KernelError::KernelNotFound(id.into())
152 }
153
154 #[must_use]
156 pub fn launch_failed(msg: impl Into<String>) -> Self {
157 KernelError::LaunchFailed(msg.into())
158 }
159
160 #[must_use]
162 pub fn device(msg: impl Into<String>) -> Self {
163 KernelError::DeviceError(msg.into())
164 }
165
166 #[must_use]
168 pub fn k2k(msg: impl Into<String>) -> Self {
169 KernelError::K2KError(msg.into())
170 }
171
172 #[must_use]
174 pub fn is_recoverable(&self) -> bool {
175 matches!(
176 self,
177 KernelError::QueueFull { .. }
178 | KernelError::QueueEmpty
179 | KernelError::Timeout(_)
180 | KernelError::ServiceUnavailable(_)
181 | KernelError::ResourceExhausted(_)
182 )
183 }
184
185 #[must_use]
187 pub fn is_client_error(&self) -> bool {
188 matches!(
189 self,
190 KernelError::KernelNotFound(_)
191 | KernelError::ValidationError(_)
192 | KernelError::DeserializationError(_)
193 | KernelError::Unauthorized(_)
194 | KernelError::DomainNotSupported(_)
195 )
196 }
197
198 #[must_use]
200 pub fn is_license_error(&self) -> bool {
201 matches!(self, KernelError::LicenseError(_))
202 }
203
204 #[must_use]
209 pub fn http_status_code(&self) -> u16 {
210 match self {
211 KernelError::KernelNotFound(_) => 404,
212 KernelError::KernelAlreadyRegistered(_) => 409,
213 KernelError::ValidationError(_) => 400,
214 KernelError::DeserializationError(_) => 400,
215 KernelError::SerializationError(_) => 500,
216 KernelError::Unauthorized(_) => 401,
217 KernelError::ResourceExhausted(_) => 429,
218 KernelError::ServiceUnavailable(_) => 503,
219 KernelError::Timeout(_) => 504,
220 KernelError::LicenseError(_) => 403,
221 KernelError::DomainNotSupported(_) => 403,
222 KernelError::QueueFull { .. } => 503,
223 KernelError::MessageTooLarge { .. } => 413,
224 _ => 500,
225 }
226 }
227
228 #[must_use]
230 pub fn error_code(&self) -> &'static str {
231 match self {
232 KernelError::KernelNotFound(_) => "KERNEL_NOT_FOUND",
233 KernelError::KernelAlreadyRegistered(_) => "KERNEL_ALREADY_REGISTERED",
234 KernelError::InvalidStateTransition { .. } => "INVALID_STATE_TRANSITION",
235 KernelError::KernelNotActive(_) => "KERNEL_NOT_ACTIVE",
236 KernelError::ValidationError(_) => "VALIDATION_ERROR",
237 KernelError::SerializationError(_) => "SERIALIZATION_ERROR",
238 KernelError::DeserializationError(_) => "DESERIALIZATION_ERROR",
239 KernelError::QueueFull { .. } => "QUEUE_FULL",
240 KernelError::QueueEmpty => "QUEUE_EMPTY",
241 KernelError::MessageTooLarge { .. } => "MESSAGE_TOO_LARGE",
242 KernelError::Timeout(_) => "TIMEOUT",
243 KernelError::LaunchFailed(_) => "LAUNCH_FAILED",
244 KernelError::CompilationError(_) => "COMPILATION_ERROR",
245 KernelError::DeviceError(_) => "DEVICE_ERROR",
246 KernelError::BackendNotAvailable(_) => "BACKEND_NOT_AVAILABLE",
247 KernelError::LicenseError(_) => "LICENSE_ERROR",
248 KernelError::SLOViolation(_) => "SLO_VIOLATION",
249 KernelError::DomainNotSupported(_) => "DOMAIN_NOT_SUPPORTED",
250 KernelError::InternalError(_) => "INTERNAL_ERROR",
251 KernelError::IoError(_) => "IO_ERROR",
252 KernelError::ConfigError(_) => "CONFIG_ERROR",
253 KernelError::ActorError(_) => "ACTOR_ERROR",
254 KernelError::RingKernelError(_) => "RINGKERNEL_ERROR",
255 KernelError::K2KError(_) => "K2K_ERROR",
256 KernelError::Unauthorized(_) => "UNAUTHORIZED",
257 KernelError::ResourceExhausted(_) => "RESOURCE_EXHAUSTED",
258 KernelError::ServiceUnavailable(_) => "SERVICE_UNAVAILABLE",
259 }
260 }
261}
262
263impl From<ringkernel_core::RingKernelError> for KernelError {
265 fn from(err: ringkernel_core::RingKernelError) -> Self {
266 KernelError::RingKernelError(err.to_string())
267 }
268}