Skip to main content

rivven_client/
error.rs

1use thiserror::Error;
2
3#[derive(Error, Debug)]
4pub enum Error {
5    #[error("Connection error: {0}")]
6    ConnectionError(String),
7
8    #[error("IO error: {0}")]
9    IoError(#[from] std::io::Error),
10
11    #[error("Serialization error: {0}")]
12    SerializationError(#[from] postcard::Error),
13
14    #[error("Protocol error: {0}")]
15    ProtocolError(#[from] rivven_protocol::ProtocolError),
16
17    #[error("Server error: {0}")]
18    ServerError(String),
19
20    #[error("Authentication failed: {0}")]
21    AuthenticationFailed(String),
22
23    #[error("Invalid response")]
24    InvalidResponse,
25
26    #[error("Response too large: {0} bytes (max: {1})")]
27    ResponseTooLarge(usize, usize),
28
29    #[error("Circuit breaker open for server: {0}")]
30    CircuitBreakerOpen(String),
31
32    #[error("Connection pool exhausted: {0}")]
33    PoolExhausted(String),
34
35    #[error("All servers unavailable")]
36    AllServersUnavailable,
37
38    #[error("Timeout: {0}")]
39    Timeout(String),
40
41    #[error("{0}")]
42    Other(String),
43}
44
45pub type Result<T> = std::result::Result<T, Error>;
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[test]
52    fn test_error_display() {
53        assert_eq!(
54            Error::ConnectionError("refused".to_string()).to_string(),
55            "Connection error: refused"
56        );
57        assert_eq!(
58            Error::ServerError("internal error".to_string()).to_string(),
59            "Server error: internal error"
60        );
61        assert_eq!(
62            Error::AuthenticationFailed("bad password".to_string()).to_string(),
63            "Authentication failed: bad password"
64        );
65        assert_eq!(Error::InvalidResponse.to_string(), "Invalid response");
66        assert_eq!(
67            Error::ResponseTooLarge(1000, 500).to_string(),
68            "Response too large: 1000 bytes (max: 500)"
69        );
70        assert_eq!(
71            Error::CircuitBreakerOpen("server1".to_string()).to_string(),
72            "Circuit breaker open for server: server1"
73        );
74        assert_eq!(
75            Error::PoolExhausted("max connections".to_string()).to_string(),
76            "Connection pool exhausted: max connections"
77        );
78        assert_eq!(
79            Error::AllServersUnavailable.to_string(),
80            "All servers unavailable"
81        );
82        assert_eq!(
83            Error::Timeout("connect".to_string()).to_string(),
84            "Timeout: connect"
85        );
86        assert_eq!(
87            Error::Other("custom error".to_string()).to_string(),
88            "custom error"
89        );
90    }
91
92    #[test]
93    fn test_error_debug() {
94        let err = Error::ConnectionError("test".to_string());
95        let debug = format!("{:?}", err);
96        assert!(debug.contains("ConnectionError"));
97        assert!(debug.contains("test"));
98    }
99
100    #[test]
101    fn test_io_error_from() {
102        let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
103        let err: Error = io_err.into();
104        assert!(matches!(err, Error::IoError(_)));
105        assert!(err.to_string().contains("file not found"));
106    }
107
108    #[test]
109    fn test_postcard_error_from() {
110        // Create a postcard deserialization error by trying to deserialize invalid data
111        let invalid_data: &[u8] = &[];
112        let result: std::result::Result<String, postcard::Error> =
113            postcard::from_bytes(invalid_data);
114        assert!(result.is_err());
115        let postcard_err = result.unwrap_err();
116        let err: Error = postcard_err.into();
117        assert!(matches!(err, Error::SerializationError(_)));
118    }
119
120    #[test]
121    fn test_result_type() {
122        fn returns_ok() -> Result<i32> {
123            Ok(42)
124        }
125
126        fn returns_err() -> Result<i32> {
127            Err(Error::InvalidResponse)
128        }
129
130        assert!(returns_ok().is_ok());
131        assert_eq!(returns_ok().unwrap(), 42);
132        assert!(returns_err().is_err());
133    }
134}