lightstreamer_rs/utils/
error.rs1#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
6pub enum LightstreamerError {
7 #[error("invalid argument: {0}")]
9 InvalidArgument(String),
10
11 #[error("invalid state: {0}")]
14 InvalidState(String),
15
16 #[error("connection error: {0}")]
18 Connection(String),
19
20 #[error("subscription error: {0}")]
22 Subscription(String),
23
24 #[error("configuration error: {0}")]
26 Configuration(String),
27
28 #[error("protocol error: {0}")]
30 Protocol(String),
31
32 #[error("channel error: {0}")]
34 Channel(String),
35
36 #[error("parse error: {0}")]
38 Parse(String),
39
40 #[error("authentication error: {0}")]
42 Authentication(String),
43
44 #[error("network error: {0}")]
46 Network(String),
47
48 #[error("timeout: {0}")]
50 Timeout(String),
51
52 #[error("lock error: {0}")]
54 Lock(String),
55}
56
57impl LightstreamerError {
58 #[cold]
60 #[must_use]
61 #[inline]
62 pub fn invalid_argument(msg: impl Into<String>) -> Self {
63 Self::InvalidArgument(msg.into())
64 }
65
66 #[cold]
68 #[must_use]
69 #[inline]
70 pub fn invalid_state(msg: impl Into<String>) -> Self {
71 Self::InvalidState(msg.into())
72 }
73
74 #[cold]
76 #[must_use]
77 #[inline]
78 pub fn connection(msg: impl Into<String>) -> Self {
79 Self::Connection(msg.into())
80 }
81
82 #[cold]
84 #[must_use]
85 #[inline]
86 pub fn subscription(msg: impl Into<String>) -> Self {
87 Self::Subscription(msg.into())
88 }
89
90 #[cold]
92 #[must_use]
93 #[inline]
94 pub fn configuration(msg: impl Into<String>) -> Self {
95 Self::Configuration(msg.into())
96 }
97
98 #[cold]
100 #[must_use]
101 #[inline]
102 pub fn protocol(msg: impl Into<String>) -> Self {
103 Self::Protocol(msg.into())
104 }
105
106 #[cold]
108 #[must_use]
109 #[inline]
110 pub fn channel(msg: impl Into<String>) -> Self {
111 Self::Channel(msg.into())
112 }
113
114 #[cold]
116 #[must_use]
117 #[inline]
118 pub fn parse(msg: impl Into<String>) -> Self {
119 Self::Parse(msg.into())
120 }
121
122 #[cold]
124 #[must_use]
125 #[inline]
126 pub fn lock(msg: impl Into<String>) -> Self {
127 Self::Lock(msg.into())
128 }
129}
130
131pub type Result<T> = std::result::Result<T, LightstreamerError>;
133
134impl From<String> for LightstreamerError {
135 fn from(s: String) -> Self {
136 LightstreamerError::InvalidArgument(s)
137 }
138}
139
140impl From<&str> for LightstreamerError {
141 fn from(s: &str) -> Self {
142 LightstreamerError::InvalidArgument(s.to_string())
143 }
144}
145
146impl From<Box<dyn std::error::Error>> for LightstreamerError {
147 fn from(e: Box<dyn std::error::Error>) -> Self {
148 LightstreamerError::InvalidState(e.to_string())
149 }
150}
151
152impl From<Box<dyn std::error::Error + Send + Sync>> for LightstreamerError {
153 fn from(e: Box<dyn std::error::Error + Send + Sync>) -> Self {
154 LightstreamerError::InvalidState(e.to_string())
155 }
156}
157
158impl From<tokio_tungstenite::tungstenite::http::Error> for LightstreamerError {
159 fn from(e: tokio_tungstenite::tungstenite::http::Error) -> Self {
160 LightstreamerError::InvalidState(e.to_string())
161 }
162}
163
164impl From<serde_urlencoded::ser::Error> for LightstreamerError {
165 fn from(e: serde_urlencoded::ser::Error) -> Self {
166 LightstreamerError::InvalidArgument(e.to_string())
167 }
168}
169
170impl From<tokio_tungstenite::tungstenite::Error> for LightstreamerError {
171 fn from(e: tokio_tungstenite::tungstenite::Error) -> Self {
172 LightstreamerError::Connection(e.to_string())
173 }
174}
175
176impl From<std::io::Error> for LightstreamerError {
177 fn from(e: std::io::Error) -> Self {
178 LightstreamerError::Connection(e.to_string())
179 }
180}
181
182impl From<tokio::sync::mpsc::error::SendError<crate::client::SubscriptionRequest>>
183 for LightstreamerError
184{
185 fn from(e: tokio::sync::mpsc::error::SendError<crate::client::SubscriptionRequest>) -> Self {
186 LightstreamerError::InvalidState(e.to_string())
187 }
188}
189
190impl From<tokio::sync::mpsc::error::TrySendError<usize>> for LightstreamerError {
191 fn from(e: tokio::sync::mpsc::error::TrySendError<usize>) -> Self {
192 LightstreamerError::Channel(e.to_string())
193 }
194}
195
196impl From<crate::connection::ReconnectionError> for LightstreamerError {
197 fn from(e: crate::connection::ReconnectionError) -> Self {
198 LightstreamerError::Connection(e.to_string())
199 }
200}
201
202impl From<std::env::VarError> for LightstreamerError {
203 fn from(e: std::env::VarError) -> Self {
204 LightstreamerError::Configuration(e.to_string())
205 }
206}
207
208#[deprecated(
211 since = "0.3.0",
212 note = "Use LightstreamerError::InvalidArgument instead"
213)]
214pub type IllegalArgumentException = LightstreamerError;
215
216#[deprecated(since = "0.3.0", note = "Use LightstreamerError::InvalidState instead")]
219pub type IllegalStateException = LightstreamerError;
220
221#[cfg(test)]
222mod tests {
223 use super::*;
224 use std::error::Error;
225
226 #[test]
227 fn test_invalid_argument_error() -> Result<()> {
228 let error = LightstreamerError::invalid_argument("Test error message");
229
230 let debug_output = format!("{:?}", error);
232 assert!(debug_output.contains("InvalidArgument"));
233 assert!(debug_output.contains("Test error message"));
234
235 assert_eq!(error.to_string(), "invalid argument: Test error message");
237
238 Ok(())
239 }
240
241 #[test]
242 fn test_invalid_state_error() -> Result<()> {
243 let error = LightstreamerError::invalid_state("Test state error");
244
245 let debug_output = format!("{:?}", error);
247 assert!(debug_output.contains("InvalidState"));
248 assert!(debug_output.contains("Test state error"));
249
250 assert_eq!(error.to_string(), "invalid state: Test state error");
252
253 Ok(())
254 }
255
256 #[test]
257 fn test_all_error_variants() -> Result<()> {
258 let errors = vec![
259 (
260 LightstreamerError::connection("conn"),
261 "connection error: conn",
262 ),
263 (
264 LightstreamerError::subscription("sub"),
265 "subscription error: sub",
266 ),
267 (
268 LightstreamerError::configuration("cfg"),
269 "configuration error: cfg",
270 ),
271 (
272 LightstreamerError::protocol("proto"),
273 "protocol error: proto",
274 ),
275 (LightstreamerError::channel("chan"), "channel error: chan"),
276 (LightstreamerError::parse("parse"), "parse error: parse"),
277 (LightstreamerError::lock("lock"), "lock error: lock"),
278 ];
279
280 for (error, expected_msg) in errors {
281 assert_eq!(error.to_string(), expected_msg);
282 }
283
284 Ok(())
285 }
286
287 #[test]
288 fn test_error_propagation() -> Result<()> {
289 fn function_that_fails() -> Result<()> {
290 Err(LightstreamerError::invalid_argument("Test propagation"))
291 }
292
293 fn propagate_error() -> Result<()> {
294 function_that_fails()?;
295 Ok(())
296 }
297
298 let result = propagate_error();
299 assert!(result.is_err());
300 if let Err(error) = result {
301 assert_eq!(error.to_string(), "invalid argument: Test propagation");
302 }
303
304 Ok(())
305 }
306
307 #[test]
308 fn test_error_conversion_to_box_dyn() -> Result<()> {
309 let error = LightstreamerError::invalid_argument("Test conversion");
310 let boxed_error: Box<dyn Error> = Box::new(error);
311 assert_eq!(boxed_error.to_string(), "invalid argument: Test conversion");
312
313 Ok(())
314 }
315
316 #[test]
317 fn test_error_as_return_type() -> Result<()> {
318 fn may_fail(value: i32) -> Result<()> {
319 if value < 0 {
320 Err(LightstreamerError::invalid_argument(
321 "Value cannot be negative",
322 ))
323 } else if value > 100 {
324 Err(LightstreamerError::invalid_state("Value too large"))
325 } else {
326 Ok(())
327 }
328 }
329
330 let result = may_fail(-10);
331 assert!(result.is_err());
332 if let Err(error) = result {
333 assert_eq!(
334 error.to_string(),
335 "invalid argument: Value cannot be negative"
336 );
337 }
338
339 let result = may_fail(150);
340 assert!(result.is_err());
341 if let Err(error) = result {
342 assert_eq!(error.to_string(), "invalid state: Value too large");
343 }
344
345 let result = may_fail(50);
346 assert!(result.is_ok());
347
348 Ok(())
349 }
350
351 #[test]
352 fn test_error_trait_methods() -> Result<()> {
353 let error = LightstreamerError::invalid_argument("Test error");
354 let error_ref: &dyn Error = &error;
355
356 assert!(error_ref.source().is_none());
358
359 Ok(())
360 }
361
362 #[test]
363 fn test_error_equality() -> Result<()> {
364 let error1 = LightstreamerError::invalid_argument("test");
365 let error2 = LightstreamerError::invalid_argument("test");
366 let error3 = LightstreamerError::invalid_state("test");
367
368 assert_eq!(error1, error2);
369 assert_ne!(error1, error3);
370
371 Ok(())
372 }
373
374 #[test]
375 fn test_error_clone() -> Result<()> {
376 let error = LightstreamerError::connection("test connection");
377 let cloned = error.clone();
378 assert_eq!(error, cloned);
379
380 Ok(())
381 }
382}