use crate::domain::Domain;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, KernelError>;
#[derive(Debug, Error)]
pub enum KernelError {
#[error("Kernel not found: {0}")]
KernelNotFound(String),
#[error("Kernel already registered: {0}")]
KernelAlreadyRegistered(String),
#[error("Invalid state transition from {from} to {to}")]
InvalidStateTransition {
from: String,
to: String,
},
#[error("Kernel is not active: {0}")]
KernelNotActive(String),
#[error("Input validation failed: {0}")]
ValidationError(String),
#[error("Serialization error: {0}")]
SerializationError(String),
#[error("Deserialization error: {0}")]
DeserializationError(String),
#[error("Message queue full (capacity: {capacity})")]
QueueFull {
capacity: usize,
},
#[error("Message queue empty")]
QueueEmpty,
#[error("Message too large: {size} bytes (max: {max} bytes)")]
MessageTooLarge {
size: usize,
max: usize,
},
#[error("Timeout waiting for response after {0:?}")]
Timeout(std::time::Duration),
#[error("Kernel launch failed: {0}")]
LaunchFailed(String),
#[error("GPU compilation error: {0}")]
CompilationError(String),
#[error("GPU device error: {0}")]
DeviceError(String),
#[error("Backend not available: {0}")]
BackendNotAvailable(String),
#[error("License error: {0}")]
LicenseError(#[from] crate::license::LicenseError),
#[error("SLO violation: {0}")]
SLOViolation(String),
#[error("Domain not supported: {0}")]
DomainNotSupported(Domain),
#[error("Internal error: {0}")]
InternalError(String),
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("Configuration error: {0}")]
ConfigError(String),
#[error("Actor error: {0}")]
ActorError(String),
#[error("RingKernel error: {0}")]
RingKernelError(String),
#[error("K2K error: {0}")]
K2KError(String),
#[error("Unauthorized: {0}")]
Unauthorized(String),
#[error("Resource exhausted: {0}")]
ResourceExhausted(String),
#[error("Service unavailable: {0}")]
ServiceUnavailable(String),
}
impl KernelError {
#[must_use]
pub fn validation(msg: impl Into<String>) -> Self {
KernelError::ValidationError(msg.into())
}
#[must_use]
pub fn internal(msg: impl Into<String>) -> Self {
KernelError::InternalError(msg.into())
}
#[must_use]
pub fn not_found(id: impl Into<String>) -> Self {
KernelError::KernelNotFound(id.into())
}
#[must_use]
pub fn launch_failed(msg: impl Into<String>) -> Self {
KernelError::LaunchFailed(msg.into())
}
#[must_use]
pub fn device(msg: impl Into<String>) -> Self {
KernelError::DeviceError(msg.into())
}
#[must_use]
pub fn k2k(msg: impl Into<String>) -> Self {
KernelError::K2KError(msg.into())
}
#[must_use]
pub fn is_recoverable(&self) -> bool {
matches!(
self,
KernelError::QueueFull { .. }
| KernelError::QueueEmpty
| KernelError::Timeout(_)
| KernelError::ServiceUnavailable(_)
| KernelError::ResourceExhausted(_)
)
}
#[must_use]
pub fn is_client_error(&self) -> bool {
matches!(
self,
KernelError::KernelNotFound(_)
| KernelError::ValidationError(_)
| KernelError::DeserializationError(_)
| KernelError::Unauthorized(_)
| KernelError::DomainNotSupported(_)
)
}
#[must_use]
pub fn is_license_error(&self) -> bool {
matches!(self, KernelError::LicenseError(_))
}
#[must_use]
pub fn http_status_code(&self) -> u16 {
match self {
KernelError::KernelNotFound(_) => 404,
KernelError::KernelAlreadyRegistered(_) => 409,
KernelError::ValidationError(_) => 400,
KernelError::DeserializationError(_) => 400,
KernelError::SerializationError(_) => 500,
KernelError::Unauthorized(_) => 401,
KernelError::ResourceExhausted(_) => 429,
KernelError::ServiceUnavailable(_) => 503,
KernelError::Timeout(_) => 504,
KernelError::LicenseError(_) => 403,
KernelError::DomainNotSupported(_) => 403,
KernelError::QueueFull { .. } => 503,
KernelError::MessageTooLarge { .. } => 413,
_ => 500,
}
}
#[must_use]
pub fn error_code(&self) -> &'static str {
match self {
KernelError::KernelNotFound(_) => "KERNEL_NOT_FOUND",
KernelError::KernelAlreadyRegistered(_) => "KERNEL_ALREADY_REGISTERED",
KernelError::InvalidStateTransition { .. } => "INVALID_STATE_TRANSITION",
KernelError::KernelNotActive(_) => "KERNEL_NOT_ACTIVE",
KernelError::ValidationError(_) => "VALIDATION_ERROR",
KernelError::SerializationError(_) => "SERIALIZATION_ERROR",
KernelError::DeserializationError(_) => "DESERIALIZATION_ERROR",
KernelError::QueueFull { .. } => "QUEUE_FULL",
KernelError::QueueEmpty => "QUEUE_EMPTY",
KernelError::MessageTooLarge { .. } => "MESSAGE_TOO_LARGE",
KernelError::Timeout(_) => "TIMEOUT",
KernelError::LaunchFailed(_) => "LAUNCH_FAILED",
KernelError::CompilationError(_) => "COMPILATION_ERROR",
KernelError::DeviceError(_) => "DEVICE_ERROR",
KernelError::BackendNotAvailable(_) => "BACKEND_NOT_AVAILABLE",
KernelError::LicenseError(_) => "LICENSE_ERROR",
KernelError::SLOViolation(_) => "SLO_VIOLATION",
KernelError::DomainNotSupported(_) => "DOMAIN_NOT_SUPPORTED",
KernelError::InternalError(_) => "INTERNAL_ERROR",
KernelError::IoError(_) => "IO_ERROR",
KernelError::ConfigError(_) => "CONFIG_ERROR",
KernelError::ActorError(_) => "ACTOR_ERROR",
KernelError::RingKernelError(_) => "RINGKERNEL_ERROR",
KernelError::K2KError(_) => "K2K_ERROR",
KernelError::Unauthorized(_) => "UNAUTHORIZED",
KernelError::ResourceExhausted(_) => "RESOURCE_EXHAUSTED",
KernelError::ServiceUnavailable(_) => "SERVICE_UNAVAILABLE",
}
}
}
impl From<ringkernel_core::RingKernelError> for KernelError {
fn from(err: ringkernel_core::RingKernelError) -> Self {
KernelError::RingKernelError(err.to_string())
}
}