Skip to main content

cg_common/
error.rs

1//! Error types for cg-common
2
3use thiserror::Error;
4
5/// Common error type for all cg-* and crypto-* tools
6#[derive(Error, Debug)]
7pub enum CgCommonError {
8    #[error("HTTP request failed: {0}")]
9    RequestError(#[from] reqwest::Error),
10
11    #[error("JSON parsing error: {0}")]
12    JsonError(#[from] serde_json::Error),
13
14    #[error("IO error: {0}")]
15    IoError(#[from] std::io::Error),
16
17    #[error("Rate limit exceeded: {0}")]
18    RateLimitExceeded(String),
19
20    #[error("Server error ({0}): {1}")]
21    ServerError(u16, String),
22
23    #[error("Client error ({0}): {1}")]
24    ClientError(u16, String),
25
26    #[error("API error: {0}")]
27    ApiError(String),
28
29    #[error("Data parsing error: {0}")]
30    DataError(String),
31
32    #[error("Request timeout: {0}")]
33    TimeoutError(String),
34
35    #[error("Max retries exceeded ({0})")]
36    MaxRetriesExceeded(u32),
37
38    #[error("Invalid coin ID or symbol: {0}")]
39    InvalidCoinId(String),
40
41    #[error("No data available: {0}")]
42    NoData(String),
43}
44
45/// Result type alias using CgCommonError
46pub type Result<T> = std::result::Result<T, CgCommonError>;
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    #[test]
53    fn test_error_display() {
54        let err = CgCommonError::RateLimitExceeded("api.coingecko.com".to_string());
55        assert!(err.to_string().contains("Rate limit"));
56    }
57
58    #[test]
59    fn test_error_from_io() {
60        let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
61        let err: CgCommonError = io_err.into();
62        assert!(matches!(err, CgCommonError::IoError(_)));
63    }
64
65    #[test]
66    fn test_server_error_display() {
67        let err = CgCommonError::ServerError(500, "Internal Server Error".to_string());
68        let display = err.to_string();
69        assert!(display.contains("500"));
70        assert!(display.contains("Internal Server Error"));
71    }
72
73    #[test]
74    fn test_invalid_coin_id() {
75        let err = CgCommonError::InvalidCoinId("INVALID".to_string());
76        assert!(err.to_string().contains("INVALID"));
77    }
78}