use std::sync::Arc;
use derive_builder::UninitializedFieldError;
pub trait ProviderError: std::error::Error + Send + Sync {}
impl PartialEq for dyn ProviderError {
fn eq(&self, other: &dyn ProviderError) -> bool {
self.to_string() == other.to_string()
}
}
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, thiserror::Error, Clone, PartialEq)]
pub enum Error {
#[error("A required field is missing: {0}")]
MissingField(String),
#[error("API error: {status_code:?} - {details}")]
ApiError {
details: String,
status_code: Option<reqwest::StatusCode>,
},
#[error("Invalid input: {0}")]
InvalidInput(String),
#[error("Tool error: {0}")]
ToolCallError(String),
#[error("Prompt error: {0}")]
PromptError(String),
#[error("AI SDK error: {0}")]
Other(String),
#[error("Provider error: {0}")]
ProviderError(Arc<dyn ProviderError>),
}
impl From<UninitializedFieldError> for Error {
fn from(err: UninitializedFieldError) -> Self {
Error::MissingField(err.field_name().to_string())
}
}
impl From<Error> for String {
fn from(value: Error) -> String {
match value {
Error::MissingField(error) => format!("Missing field: {error}"),
Error::ApiError {
details,
status_code,
} => {
format!("API error: {status_code:?} - {details}")
}
Error::InvalidInput(error) => format!("Invalid input: {error}"),
Error::ToolCallError(error) => format!("Tool error: {error}"),
Error::Other(error) => format!("Other error: {error}"),
Error::ProviderError(error) => format!("Provider error: {error}"),
Error::PromptError(error) => format!("Prompt error: {error}"),
}
}
}