use thiserror::Error;
#[derive(Error, Debug)]
pub enum OpenCratesError {
#[error("Configuration error: {0}")]
Config(String),
#[error("Template error: {0}")]
Template(String),
#[error("Provider error: {0}")]
Provider(String),
#[error("Search error: {0}")]
Search(String),
#[error("Cache error: {0}")]
Cache(String),
#[error("Resource '{resource}' with id '{id}' not found")]
NotFound { resource: String, id: String },
#[error("Internal error: {0}")]
Internal(String),
#[error("External error: {0}")]
External(String),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("Serialization error: {0}")]
Serialization(#[from] serde_json::Error),
#[error("HTTP error: {0}")]
Http(#[from] reqwest::Error),
#[error("Redis error: {0}")]
Redis(String),
#[error("Validation error: {0}")]
Validation(String),
#[error("Authentication error: {0}")]
Auth(String),
#[error("Rate limit exceeded: {0}")]
RateLimit(String),
#[error("Network error: {0}")]
Network(String),
#[error("Parse error: {0}")]
Parse(String),
#[error("Unknown error: {0}")]
Unknown(String),
}
impl OpenCratesError {
pub fn config(message: impl Into<String>) -> Self {
Self::Config(message.into())
}
pub fn template(template_name: impl Into<String>) -> Self {
Self::Template(format!("Template '{}' not found", template_name.into()))
}
pub fn provider(provider: impl Into<String>) -> Self {
Self::Provider(format!("Provider '{}' error", provider.into()))
}
pub fn search(message: impl Into<String>) -> Self {
Self::Search(message.into())
}
pub fn cache(message: impl Into<String>) -> Self {
Self::Cache(message.into())
}
pub fn not_found(resource: impl Into<String>, id: impl Into<String>) -> Self {
Self::NotFound {
resource: resource.into(),
id: id.into(),
}
}
pub fn internal(message: impl Into<String>) -> Self {
Self::Internal(message.into())
}
pub fn external(message: impl Into<String>) -> Self {
Self::External(message.into())
}
pub fn redis(message: impl Into<String>) -> Self {
Self::Redis(message.into())
}
pub fn validation(message: impl Into<String>) -> Self {
Self::Validation(message.into())
}
pub fn auth(message: impl Into<String>) -> Self {
Self::Auth(message.into())
}
pub fn rate_limit(message: impl Into<String>) -> Self {
Self::RateLimit(message.into())
}
pub fn network(message: impl Into<String>) -> Self {
Self::Network(message.into())
}
pub fn parse(message: impl Into<String>) -> Self {
Self::Parse(message.into())
}
pub fn unknown(message: impl Into<String>) -> Self {
Self::Unknown(message.into())
}
}
#[cfg(feature = "redis")]
impl From<redis::RedisError> for OpenCratesError {
fn from(error: redis::RedisError) -> Self {
Self::Redis(error.to_string())
}
}
impl From<anyhow::Error> for OpenCratesError {
fn from(error: anyhow::Error) -> Self {
Self::External(error.to_string())
}
}