1pub type Result<T> = std::result::Result<T, Error>;
5
6#[derive(Debug, thiserror::Error)]
8pub enum Error {
9 #[error("Validation error: {message}")]
11 Validation {
12 message: String,
14 },
15
16 #[error("Routing error: {message}")]
18 Routing {
19 message: String,
21 },
22
23 #[error("Proxy error: {message}")]
25 Proxy {
26 message: String,
28 },
29
30 #[error("Latency simulation error: {message}")]
32 Latency {
33 message: String,
35 },
36
37 #[error("Configuration error: {message}")]
39 Config {
40 message: String,
42 },
43
44 #[error("Protocol not found: {message}")]
46 ProtocolNotFound {
47 message: String,
49 },
50
51 #[error("Protocol disabled: {message}")]
53 ProtocolDisabled {
54 message: String,
56 },
57
58 #[error("Protocol handler in use: {message}")]
60 ProtocolHandlerInUse {
61 message: String,
63 },
64
65 #[error("Protocol validation error: {message}")]
67 ProtocolValidationError {
68 protocol: String,
70 message: String,
72 },
73
74 #[error("IO error: {0}")]
76 Io(#[from] std::io::Error),
77
78 #[error("JSON error: {0}")]
80 Json(#[from] serde_json::Error),
81
82 #[error("YAML error: {0}")]
84 Yaml(#[from] serde_yaml::Error),
85
86 #[error("HTTP error: {0}")]
88 Http(#[from] reqwest::Error),
89
90 #[error("URL parse error: {0}")]
92 UrlParse(#[from] url::ParseError),
93
94 #[error("Regex error: {0}")]
96 Regex(#[from] regex::Error),
97
98 #[error("Generic error: {0}")]
100 Generic(String),
101
102 #[error("Encryption error: {0}")]
104 Encryption(#[from] crate::encryption::EncryptionError),
105
106 #[error("JavaScript error: {0}")]
108 JavaScript(#[from] rquickjs::Error),
109}
110
111impl From<String> for Error {
112 fn from(message: String) -> Self {
113 Self::Generic(message)
114 }
115}
116
117impl Error {
118 pub fn validation<S: Into<String>>(message: S) -> Self {
120 Self::Validation {
121 message: message.into(),
122 }
123 }
124
125 pub fn routing<S: Into<String>>(message: S) -> Self {
127 Self::Routing {
128 message: message.into(),
129 }
130 }
131
132 pub fn proxy<S: Into<String>>(message: S) -> Self {
134 Self::Proxy {
135 message: message.into(),
136 }
137 }
138
139 pub fn latency<S: Into<String>>(message: S) -> Self {
141 Self::Latency {
142 message: message.into(),
143 }
144 }
145
146 pub fn config<S: Into<String>>(message: S) -> Self {
148 Self::Config {
149 message: message.into(),
150 }
151 }
152
153 pub fn protocol_not_found<S: Into<String>>(message: S) -> Self {
155 Self::ProtocolNotFound {
156 message: message.into(),
157 }
158 }
159
160 pub fn protocol_disabled<S: Into<String>>(message: S) -> Self {
162 Self::ProtocolDisabled {
163 message: message.into(),
164 }
165 }
166
167 pub fn protocol_handler_in_use<S: Into<String>>(message: S) -> Self {
169 Self::ProtocolHandlerInUse {
170 message: message.into(),
171 }
172 }
173
174 pub fn protocol_validation_error<S: Into<String>>(protocol: S, message: S) -> Self {
176 Self::ProtocolValidationError {
177 protocol: protocol.into(),
178 message: message.into(),
179 }
180 }
181
182 pub fn generic<S: Into<String>>(message: S) -> Self {
184 Self::Generic(message.into())
185 }
186}
187
188#[cfg(test)]
189mod tests {
190 use super::*;
191
192 #[test]
193 fn test_validation_error() {
194 let err = Error::validation("test validation");
195 assert!(err.to_string().contains("Validation error"));
196 assert!(err.to_string().contains("test validation"));
197 }
198
199 #[test]
200 fn test_routing_error() {
201 let err = Error::routing("test routing");
202 assert!(err.to_string().contains("Routing error"));
203 assert!(err.to_string().contains("test routing"));
204 }
205
206 #[test]
207 fn test_proxy_error() {
208 let err = Error::proxy("test proxy");
209 assert!(err.to_string().contains("Proxy error"));
210 assert!(err.to_string().contains("test proxy"));
211 }
212
213 #[test]
214 fn test_latency_error() {
215 let err = Error::latency("test latency");
216 assert!(err.to_string().contains("Latency simulation error"));
217 assert!(err.to_string().contains("test latency"));
218 }
219
220 #[test]
221 fn test_config_error() {
222 let err = Error::config("test config");
223 assert!(err.to_string().contains("Configuration error"));
224 assert!(err.to_string().contains("test config"));
225 }
226
227 #[test]
228 fn test_generic_error() {
229 let err = Error::generic("test generic");
230 assert!(err.to_string().contains("Generic error"));
231 assert!(err.to_string().contains("test generic"));
232 }
233
234 #[test]
235 fn test_from_string() {
236 let err: Error = "test message".to_string().into();
237 assert!(matches!(err, Error::Generic(_)));
238 assert!(err.to_string().contains("test message"));
239 }
240
241 #[test]
242 fn test_json_error_conversion() {
243 let json_err = serde_json::from_str::<serde_json::Value>("invalid json");
244 assert!(json_err.is_err());
245 let err: Error = json_err.unwrap_err().into();
246 assert!(matches!(err, Error::Json(_)));
247 }
248
249 #[test]
250 fn test_url_parse_error_conversion() {
251 let url_err = url::Url::parse("not a url");
252 assert!(url_err.is_err());
253 let err: Error = url_err.unwrap_err().into();
254 assert!(matches!(err, Error::UrlParse(_)));
255 }
256
257 #[test]
258 #[allow(clippy::invalid_regex)]
259 fn test_regex_error_conversion() {
260 let regex_err = regex::Regex::new("[invalid(");
261 assert!(regex_err.is_err());
262 let err: Error = regex_err.unwrap_err().into();
263 assert!(matches!(err, Error::Regex(_)));
264 }
265
266 #[test]
267 fn test_error_display() {
268 let errors = vec![
269 (Error::validation("msg"), "Validation error: msg"),
270 (Error::routing("msg"), "Routing error: msg"),
271 (Error::proxy("msg"), "Proxy error: msg"),
272 (Error::latency("msg"), "Latency simulation error: msg"),
273 (Error::config("msg"), "Configuration error: msg"),
274 (Error::generic("msg"), "Generic error: msg"),
275 ];
276
277 for (err, expected) in errors {
278 assert_eq!(err.to_string(), expected);
279 }
280 }
281}