Skip to main content

kode_bridge/
errors.rs

1use std::fmt;
2use thiserror::Error;
3
4/// Comprehensive error types for kode-bridge
5#[derive(Error, Debug)]
6pub enum KodeBridgeError {
7    #[error("IO error: {0}")]
8    Io(#[from] std::io::Error),
9
10    #[error("JSON serialization error: {0}")]
11    Json(#[from] serde_json::Error),
12
13    #[error("HTTP parsing error: {0}")]
14    HttpParse(#[from] httparse::Error),
15
16    #[error("HTTP error: {0}")]
17    Http(#[from] http::Error),
18
19    #[error("Invalid status code: {0}")]
20    InvalidStatusCode(#[from] http::status::InvalidStatusCode),
21
22    #[error("UTF-8 conversion error: {0}")]
23    Utf8(#[from] std::str::Utf8Error),
24
25    #[error("String conversion error: {0}")]
26    FromUtf8(#[from] std::string::FromUtf8Error),
27
28    #[error("Connection error: {message}")]
29    Connection { message: String },
30
31    #[error("Timeout error: operation timed out after {duration_ms}ms")]
32    Timeout { duration_ms: u64 },
33
34    #[error("Protocol error: {message}")]
35    Protocol { message: String },
36
37    #[error("Configuration error: {message}")]
38    Configuration { message: String },
39
40    #[error("Invalid request: {message}")]
41    InvalidRequest { message: String },
42
43    #[error("Server error: HTTP {status}")]
44    ServerError { status: u16 },
45
46    #[error("Client error: HTTP {status}")]
47    ClientError { status: u16 },
48
49    #[error("Stream closed unexpectedly")]
50    StreamClosed,
51
52    #[error("JSON serialization error: {message}")]
53    JsonSerialize { message: String },
54
55    #[error("Pool exhausted: no available connections")]
56    PoolExhausted,
57
58    #[error("Custom error: {message}")]
59    Custom { message: String },
60}
61
62impl KodeBridgeError {
63    pub fn connection<S: Into<String>>(message: S) -> Self {
64        Self::Connection {
65            message: message.into(),
66        }
67    }
68
69    pub const fn timeout(duration_ms: u64) -> Self {
70        Self::Timeout { duration_ms }
71    }
72
73    pub fn timeout_msg<S: Into<String>>(_message: S) -> Self {
74        // Convert to a reasonable duration for now
75        Self::Timeout { duration_ms: 30000 }
76    }
77
78    pub fn protocol<S: Into<String>>(message: S) -> Self {
79        Self::Protocol {
80            message: message.into(),
81        }
82    }
83
84    pub fn configuration<S: Into<String>>(message: S) -> Self {
85        Self::Configuration {
86            message: message.into(),
87        }
88    }
89
90    pub fn invalid_request<S: Into<String>>(message: S) -> Self {
91        Self::InvalidRequest {
92            message: message.into(),
93        }
94    }
95
96    pub fn custom<S: Into<String>>(message: S) -> Self {
97        Self::Custom {
98            message: message.into(),
99        }
100    }
101
102    pub fn json_serialize<S: Into<String>>(message: S) -> Self {
103        Self::JsonSerialize {
104            message: message.into(),
105        }
106    }
107
108    pub fn json_parse<S: Into<String>>(message: S) -> Self {
109        Self::JsonSerialize {
110            message: message.into(),
111        }
112    }
113
114    pub fn validation<S: Into<String>>(message: S) -> Self {
115        Self::Configuration {
116            message: message.into(),
117        }
118    }
119
120    /// Check if error is retriable
121    pub const fn is_retriable(&self) -> bool {
122        matches!(
123            self,
124            Self::Io(_) | Self::Connection { .. } | Self::Timeout { .. } | Self::StreamClosed
125        )
126    }
127
128    /// Check if error is a client error
129    pub const fn is_client_error(&self) -> bool {
130        matches!(self, Self::ClientError { .. } | Self::InvalidRequest { .. })
131    }
132
133    /// Check if error is a server error
134    pub const fn is_server_error(&self) -> bool {
135        matches!(self, Self::ServerError { .. })
136    }
137}
138
139/// Result type for kode-bridge operations
140pub type Result<T> = std::result::Result<T, KodeBridgeError>;
141
142/// Legacy compatibility
143pub type AnyError = Box<dyn std::error::Error + Send + Sync + 'static>;
144pub type AnyResult<T> = std::result::Result<T, AnyError>;
145
146/// Convert AnyError to KodeBridgeError
147impl From<AnyError> for KodeBridgeError {
148    fn from(err: AnyError) -> Self {
149        Self::custom(err.to_string())
150    }
151}
152
153/// Simple string error for backward compatibility
154#[derive(Debug)]
155pub struct ErrorString(String);
156
157impl fmt::Display for ErrorString {
158    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
159        f.write_str(&self.0)
160    }
161}
162
163impl std::error::Error for ErrorString {}
164
165impl From<String> for ErrorString {
166    fn from(s: String) -> Self {
167        Self(s)
168    }
169}
170
171impl From<&str> for ErrorString {
172    fn from(s: &str) -> Self {
173        Self(s.to_string())
174    }
175}