ringkernel_ecosystem/
error.rs1use thiserror::Error;
4
5#[derive(Error, Debug)]
7pub enum EcosystemError {
8 #[error("RingKernel error: {0}")]
10 RingKernel(#[from] ringkernel_core::error::RingKernelError),
11
12 #[error("Operation timed out after {0:?}")]
14 Timeout(std::time::Duration),
15
16 #[error("Kernel not found: {0}")]
18 KernelNotFound(String),
19
20 #[error("Configuration error: {0}")]
22 Config(String),
23
24 #[error("Serialization error: {0}")]
26 Serialization(String),
27
28 #[error("Deserialization error: {0}")]
30 Deserialization(String),
31
32 #[error("Data conversion error: {0}")]
34 DataConversion(String),
35
36 #[error("Service unavailable: {0}")]
38 ServiceUnavailable(String),
39
40 #[error("Internal error: {0}")]
42 Internal(String),
43
44 #[cfg(feature = "actix")]
46 #[error("Actor error: {0}")]
47 Actor(String),
48
49 #[cfg(feature = "grpc")]
51 #[error("gRPC error: {0}")]
52 Grpc(String),
53
54 #[cfg(feature = "arrow")]
56 #[error("Arrow error: {0}")]
57 Arrow(String),
58
59 #[cfg(feature = "polars")]
61 #[error("Polars error: {0}")]
62 Polars(String),
63
64 #[cfg(feature = "candle")]
66 #[error("Candle error: {0}")]
67 Candle(String),
68
69 #[cfg(feature = "persistent")]
71 #[error("Persistent kernel error: {0}")]
72 Persistent(String),
73
74 #[cfg(feature = "persistent")]
76 #[error("Command queue full")]
77 QueueFull,
78
79 #[cfg(feature = "persistent")]
81 #[error("Kernel not running: {0}")]
82 KernelNotRunning(String),
83
84 #[cfg(feature = "persistent")]
86 #[error("Command failed (code {code}): {message}")]
87 CommandFailed {
88 code: u32,
90 message: String,
92 },
93}
94
95pub type Result<T> = std::result::Result<T, EcosystemError>;
97
98#[cfg(feature = "axum")]
100#[derive(Debug)]
101pub struct AppError(pub EcosystemError);
102
103#[cfg(feature = "axum")]
104impl std::fmt::Display for AppError {
105 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106 write!(f, "{}", self.0)
107 }
108}
109
110#[cfg(feature = "axum")]
111impl std::error::Error for AppError {}
112
113#[cfg(feature = "axum")]
114impl axum::response::IntoResponse for AppError {
115 fn into_response(self) -> axum::response::Response {
116 use axum::http::StatusCode;
117
118 let status = match &self.0 {
119 EcosystemError::KernelNotFound(_) => StatusCode::NOT_FOUND,
120 EcosystemError::Timeout(_) => StatusCode::GATEWAY_TIMEOUT,
121 EcosystemError::Config(_) => StatusCode::BAD_REQUEST,
122 EcosystemError::ServiceUnavailable(_) => StatusCode::SERVICE_UNAVAILABLE,
123 _ => StatusCode::INTERNAL_SERVER_ERROR,
124 };
125
126 (status, self.0.to_string()).into_response()
127 }
128}
129
130#[cfg(feature = "axum")]
131impl From<EcosystemError> for AppError {
132 fn from(err: EcosystemError) -> Self {
133 AppError(err)
134 }
135}
136
137#[cfg(feature = "grpc")]
138impl From<EcosystemError> for tonic::Status {
139 fn from(err: EcosystemError) -> Self {
140 use tonic::Code;
141
142 let code = match &err {
143 EcosystemError::KernelNotFound(_) => Code::NotFound,
144 EcosystemError::Timeout(_) => Code::DeadlineExceeded,
145 EcosystemError::Config(_) => Code::InvalidArgument,
146 EcosystemError::ServiceUnavailable(_) => Code::Unavailable,
147 _ => Code::Internal,
148 };
149
150 tonic::Status::new(code, err.to_string())
151 }
152}