use thiserror::Error;
pub type CrabResult<T> = Result<T, CrabError>;
#[derive(Debug, Error)]
pub enum CrabError {
#[error("Missing consumer key (API key)")]
MissingConsumerKey,
#[error("Missing consumer secret")]
MissingConsumerSecret,
#[error("Missing access token")]
MissingAccessToken,
#[error("Invalid User-Agent header value")]
InvalidUserAgent,
#[error("Failed to construct HTTP client: {0}")]
HttpClient(#[source] reqwest::Error),
#[error("HTTP request failed: {0}")]
Http(#[from] reqwest::Error),
#[error("API error (status {status}): {message}")]
Api {
status: u16,
message: String,
},
#[error("Rate limit exceeded. Retry after: {retry_after:?} seconds")]
RateLimit {
retry_after: Option<u64>,
},
#[error("Authentication failed: {0}")]
Auth(String),
#[error("OAuth error: {0}")]
OAuth(String),
#[error("Serialization error: {0}")]
Serialization(#[from] serde_json::Error),
#[error("Invalid URL: {0}")]
Url(#[from] url::ParseError),
#[error("Invalid API response: {0}")]
InvalidResponse(String),
#[error("Resource not found: {0}")]
NotFound(String),
#[error("Invalid parameter: {0}")]
InvalidParameter(String),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display() {
let err = CrabError::MissingConsumerKey;
assert_eq!(err.to_string(), "Missing consumer key (API key)");
let err = CrabError::RateLimit {
retry_after: Some(60),
};
assert_eq!(
err.to_string(),
"Rate limit exceeded. Retry after: Some(60) seconds"
);
let err = CrabError::Api {
status: 404,
message: "Blog not found".to_string(),
};
assert_eq!(err.to_string(), "API error (status 404): Blog not found");
}
}