fmp_rs/
error.rs

1//! Error types for the FMP client.
2
3use thiserror::Error;
4
5/// Result type alias using our Error type
6pub type Result<T> = std::result::Result<T, Error>;
7
8/// Errors that can occur when using the FMP client
9#[derive(Debug, Error)]
10pub enum Error {
11    /// Error from the HTTP client
12    #[error("HTTP request failed: {0}")]
13    Http(#[from] reqwest::Error),
14
15    /// Error parsing JSON response
16    #[error("Failed to parse JSON: {0}")]
17    Json(#[from] serde_json::Error),
18
19    /// API returned an error response
20    #[error("API error: {message} (status: {status})")]
21    Api { status: u16, message: String },
22
23    /// Missing API key
24    #[error("API key not found. Please set FMP_API_KEY environment variable")]
25    MissingApiKey,
26
27    /// Invalid API key format
28    #[error("Invalid API key format")]
29    InvalidApiKey,
30
31    /// Invalid parameter
32    #[error("Invalid parameter: {0}")]
33    InvalidParameter(String),
34
35    /// Rate limit exceeded
36    #[error("Rate limit exceeded. Please try again later")]
37    RateLimitExceeded,
38
39    /// Resource not found
40    #[error("Resource not found: {0}")]
41    NotFound(String),
42
43    /// URL parsing error
44    #[error("Failed to parse URL: {0}")]
45    UrlParse(#[from] url::ParseError),
46
47    /// Generic error with custom message
48    #[error("{0}")]
49    Custom(String),
50}
51
52impl Error {
53    /// Create a new API error
54    pub fn api(status: u16, message: impl Into<String>) -> Self {
55        Self::Api {
56            status,
57            message: message.into(),
58        }
59    }
60
61    /// Create a new custom error
62    pub fn custom(message: impl Into<String>) -> Self {
63        Self::Custom(message.into())
64    }
65
66    /// Check if this is a rate limit error
67    pub fn is_rate_limit(&self) -> bool {
68        matches!(self, Error::RateLimitExceeded)
69            || matches!(self, Error::Api { status, .. } if *status == 429)
70    }
71
72    /// Check if this is a not found error
73    pub fn is_not_found(&self) -> bool {
74        matches!(self, Error::NotFound(_))
75            || matches!(self, Error::Api { status, .. } if *status == 404)
76    }
77}