use thiserror::Error;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Error, Debug)]
pub enum Error {
#[error("HTTP request failed: {0}")]
HttpError(#[from] reqwest::Error),
#[error("JSON parsing failed: {0}")]
JsonError(#[from] serde_json::Error),
#[error("Invalid response: {0}")]
InvalidResponse(String),
#[error("Provider not found: {0}")]
ProviderNotFound(String),
#[error("Unknown provider for model: {0}")]
UnknownProvider(String),
#[error("Invalid model format: {0}")]
InvalidModel(String),
#[error("API key not found for provider: {0}")]
MissingApiKey(String),
#[error("Rate limit exceeded: {0}")]
RateLimitExceeded(String),
#[error("Provider error: {0}")]
ProviderError(String),
#[error("Streaming error: {0}")]
StreamError(String),
#[error("Configuration error: {0}")]
ConfigError(String),
#[error("Network error: {0}")]
NetworkError(String),
#[error("{0}")]
Other(String),
}
impl Error {
pub fn provider_error(msg: impl Into<String>) -> Self {
Self::ProviderError(msg.into())
}
pub fn invalid_response(msg: impl Into<String>) -> Self {
Self::InvalidResponse(msg.into())
}
pub fn stream_error(msg: impl Into<String>) -> Self {
Self::StreamError(msg.into())
}
pub fn from_unparseable_chunk(data: &str, fallback_label: &str) -> Self {
if let Ok(json) = serde_json::from_str::<serde_json::Value>(data)
&& let Some(error) = json.get("error")
{
let message = error
.get("message")
.and_then(|m| m.as_str())
.unwrap_or("Unknown error");
let error_type = error
.get("type")
.or_else(|| error.get("status"))
.and_then(|t| t.as_str())
.unwrap_or("unknown");
return Self::ProviderError(format!("{}: {}", error_type, message));
}
let preview: String = data.chars().take(200).collect();
Self::StreamError(format!("{}: {}", fallback_label, preview))
}
}