rustkernel_core/
error.rs

1//! Error types for RustKernels.
2
3use crate::domain::Domain;
4use thiserror::Error;
5
6/// Result type alias using `KernelError`.
7pub type Result<T> = std::result::Result<T, KernelError>;
8
9/// Errors that can occur during kernel operations.
10#[derive(Debug, Error)]
11pub enum KernelError {
12    /// Kernel not found in registry.
13    #[error("Kernel not found: {0}")]
14    KernelNotFound(String),
15
16    /// Kernel already registered.
17    #[error("Kernel already registered: {0}")]
18    KernelAlreadyRegistered(String),
19
20    /// Invalid kernel state transition.
21    #[error("Invalid state transition from {from} to {to}")]
22    InvalidStateTransition {
23        /// Current state.
24        from: String,
25        /// Attempted target state.
26        to: String,
27    },
28
29    /// Kernel is not in active state.
30    #[error("Kernel is not active: {0}")]
31    KernelNotActive(String),
32
33    /// Input validation failed.
34    #[error("Input validation failed: {0}")]
35    ValidationError(String),
36
37    /// Serialization error.
38    #[error("Serialization error: {0}")]
39    SerializationError(String),
40
41    /// Deserialization error.
42    #[error("Deserialization error: {0}")]
43    DeserializationError(String),
44
45    /// Message queue is full.
46    #[error("Message queue full (capacity: {capacity})")]
47    QueueFull {
48        /// Queue capacity.
49        capacity: usize,
50    },
51
52    /// Message queue is empty.
53    #[error("Message queue empty")]
54    QueueEmpty,
55
56    /// Message too large for queue.
57    #[error("Message too large: {size} bytes (max: {max} bytes)")]
58    MessageTooLarge {
59        /// Actual message size.
60        size: usize,
61        /// Maximum allowed size.
62        max: usize,
63    },
64
65    /// Timeout waiting for response.
66    #[error("Timeout waiting for response after {0:?}")]
67    Timeout(std::time::Duration),
68
69    /// GPU kernel launch failed.
70    #[error("Kernel launch failed: {0}")]
71    LaunchFailed(String),
72
73    /// GPU compilation error.
74    #[error("GPU compilation error: {0}")]
75    CompilationError(String),
76
77    /// GPU device error.
78    #[error("GPU device error: {0}")]
79    DeviceError(String),
80
81    /// Backend not available.
82    #[error("Backend not available: {0}")]
83    BackendNotAvailable(String),
84
85    /// License error.
86    #[error("License error: {0}")]
87    LicenseError(#[from] crate::license::LicenseError),
88
89    /// SLO violation.
90    #[error("SLO violation: {0}")]
91    SLOViolation(String),
92
93    /// Domain not supported.
94    #[error("Domain not supported: {0}")]
95    DomainNotSupported(Domain),
96
97    /// Internal error.
98    #[error("Internal error: {0}")]
99    InternalError(String),
100
101    /// IO error.
102    #[error("IO error: {0}")]
103    IoError(#[from] std::io::Error),
104
105    /// Configuration error.
106    #[error("Configuration error: {0}")]
107    ConfigError(String),
108
109    /// Actor error.
110    #[error("Actor error: {0}")]
111    ActorError(String),
112
113    /// RingKernel error (from underlying runtime).
114    #[error("RingKernel error: {0}")]
115    RingKernelError(String),
116
117    /// K2K (Kernel-to-Kernel) communication error.
118    #[error("K2K error: {0}")]
119    K2KError(String),
120}
121
122impl KernelError {
123    /// Create a validation error.
124    #[must_use]
125    pub fn validation(msg: impl Into<String>) -> Self {
126        KernelError::ValidationError(msg.into())
127    }
128
129    /// Create an internal error.
130    #[must_use]
131    pub fn internal(msg: impl Into<String>) -> Self {
132        KernelError::InternalError(msg.into())
133    }
134
135    /// Create a kernel not found error.
136    #[must_use]
137    pub fn not_found(id: impl Into<String>) -> Self {
138        KernelError::KernelNotFound(id.into())
139    }
140
141    /// Create a launch failed error.
142    #[must_use]
143    pub fn launch_failed(msg: impl Into<String>) -> Self {
144        KernelError::LaunchFailed(msg.into())
145    }
146
147    /// Create a device error.
148    #[must_use]
149    pub fn device(msg: impl Into<String>) -> Self {
150        KernelError::DeviceError(msg.into())
151    }
152
153    /// Create a K2K error.
154    #[must_use]
155    pub fn k2k(msg: impl Into<String>) -> Self {
156        KernelError::K2KError(msg.into())
157    }
158
159    /// Returns true if this is a recoverable error.
160    #[must_use]
161    pub fn is_recoverable(&self) -> bool {
162        matches!(
163            self,
164            KernelError::QueueFull { .. }
165                | KernelError::QueueEmpty
166                | KernelError::Timeout(_)
167                | KernelError::ValidationError(_)
168        )
169    }
170
171    /// Returns true if this is a license-related error.
172    #[must_use]
173    pub fn is_license_error(&self) -> bool {
174        matches!(self, KernelError::LicenseError(_))
175    }
176}
177
178/// Convert from ringkernel-core errors.
179impl From<ringkernel_core::RingKernelError> for KernelError {
180    fn from(err: ringkernel_core::RingKernelError) -> Self {
181        KernelError::RingKernelError(err.to_string())
182    }
183}