1use std::fmt;
2use thiserror::Error;
3
4#[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 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 pub const fn is_retriable(&self) -> bool {
122 matches!(
123 self,
124 Self::Io(_) | Self::Connection { .. } | Self::Timeout { .. } | Self::StreamClosed
125 )
126 }
127
128 pub const fn is_client_error(&self) -> bool {
130 matches!(self, Self::ClientError { .. } | Self::InvalidRequest { .. })
131 }
132
133 pub const fn is_server_error(&self) -> bool {
135 matches!(self, Self::ServerError { .. })
136 }
137}
138
139pub type Result<T> = std::result::Result<T, KodeBridgeError>;
141
142pub type AnyError = Box<dyn std::error::Error + Send + Sync + 'static>;
144pub type AnyResult<T> = std::result::Result<T, AnyError>;
145
146impl From<AnyError> for KodeBridgeError {
148 fn from(err: AnyError) -> Self {
149 Self::custom(err.to_string())
150 }
151}
152
153#[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}