ringkernel_ecosystem/
error.rs

1//! Error types for ecosystem integrations.
2
3use thiserror::Error;
4
5/// Ecosystem integration error type.
6#[derive(Error, Debug)]
7pub enum EcosystemError {
8    /// RingKernel core error.
9    #[error("RingKernel error: {0}")]
10    RingKernel(#[from] ringkernel_core::error::RingKernelError),
11
12    /// Timeout waiting for response.
13    #[error("Operation timed out after {0:?}")]
14    Timeout(std::time::Duration),
15
16    /// Kernel not found.
17    #[error("Kernel not found: {0}")]
18    KernelNotFound(String),
19
20    /// Invalid configuration.
21    #[error("Configuration error: {0}")]
22    Config(String),
23
24    /// Serialization error.
25    #[error("Serialization error: {0}")]
26    Serialization(String),
27
28    /// Deserialization error.
29    #[error("Deserialization error: {0}")]
30    Deserialization(String),
31
32    /// Data conversion error.
33    #[error("Data conversion error: {0}")]
34    DataConversion(String),
35
36    /// Service unavailable.
37    #[error("Service unavailable: {0}")]
38    ServiceUnavailable(String),
39
40    /// Internal error.
41    #[error("Internal error: {0}")]
42    Internal(String),
43
44    /// Actor error (for actix integration).
45    #[cfg(feature = "actix")]
46    #[error("Actor error: {0}")]
47    Actor(String),
48
49    /// gRPC error (for tonic integration).
50    #[cfg(feature = "grpc")]
51    #[error("gRPC error: {0}")]
52    Grpc(String),
53
54    /// Arrow error (for arrow integration).
55    #[cfg(feature = "arrow")]
56    #[error("Arrow error: {0}")]
57    Arrow(String),
58
59    /// Polars error (for polars integration).
60    #[cfg(feature = "polars")]
61    #[error("Polars error: {0}")]
62    Polars(String),
63
64    /// Candle error (for ML integration).
65    #[cfg(feature = "candle")]
66    #[error("Candle error: {0}")]
67    Candle(String),
68}
69
70/// Result type for ecosystem operations.
71pub type Result<T> = std::result::Result<T, EcosystemError>;
72
73/// Error that can be returned from Axum handlers.
74#[cfg(feature = "axum")]
75#[derive(Debug)]
76pub struct AppError(pub EcosystemError);
77
78#[cfg(feature = "axum")]
79impl std::fmt::Display for AppError {
80    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81        write!(f, "{}", self.0)
82    }
83}
84
85#[cfg(feature = "axum")]
86impl std::error::Error for AppError {}
87
88#[cfg(feature = "axum")]
89impl axum::response::IntoResponse for AppError {
90    fn into_response(self) -> axum::response::Response {
91        use axum::http::StatusCode;
92
93        let status = match &self.0 {
94            EcosystemError::KernelNotFound(_) => StatusCode::NOT_FOUND,
95            EcosystemError::Timeout(_) => StatusCode::GATEWAY_TIMEOUT,
96            EcosystemError::Config(_) => StatusCode::BAD_REQUEST,
97            EcosystemError::ServiceUnavailable(_) => StatusCode::SERVICE_UNAVAILABLE,
98            _ => StatusCode::INTERNAL_SERVER_ERROR,
99        };
100
101        (status, self.0.to_string()).into_response()
102    }
103}
104
105#[cfg(feature = "axum")]
106impl From<EcosystemError> for AppError {
107    fn from(err: EcosystemError) -> Self {
108        AppError(err)
109    }
110}
111
112#[cfg(feature = "grpc")]
113impl From<EcosystemError> for tonic::Status {
114    fn from(err: EcosystemError) -> Self {
115        use tonic::Code;
116
117        let code = match &err {
118            EcosystemError::KernelNotFound(_) => Code::NotFound,
119            EcosystemError::Timeout(_) => Code::DeadlineExceeded,
120            EcosystemError::Config(_) => Code::InvalidArgument,
121            EcosystemError::ServiceUnavailable(_) => Code::Unavailable,
122            _ => Code::Internal,
123        };
124
125        tonic::Status::new(code, err.to_string())
126    }
127}