Skip to main content

potato_provider/
error.rs

1use gcloud_auth::error::Error as GCloudAuthError;
2use pyo3::exceptions::PyRuntimeError;
3use pyo3::pyclass::PyClassGuardError;
4use pyo3::PyErr;
5use reqwest::StatusCode;
6use thiserror::Error;
7use tracing::error;
8
9#[derive(Error, Debug)]
10pub enum ProviderError {
11    #[error("Error: {0}")]
12    Error(String),
13
14    #[error("Failed to downcast Python object: {0}")]
15    DowncastError(String),
16
17    #[error("Client did not provide response")]
18    ClientNoResponseError,
19
20    #[error("Failed to create header value for the agent client")]
21    CreateHeaderValueError(#[from] reqwest::header::InvalidHeaderValue),
22
23    #[error("Failed to create header name for the agent client")]
24    CreateHeaderNameError(#[from] reqwest::header::InvalidHeaderName),
25
26    #[error("Failed to create agent client: {0}")]
27    CreateClientError(#[source] reqwest::Error),
28
29    #[error("Request failed: {0}")]
30    RequestError(#[from] reqwest::Error),
31
32    #[error("Failed to serialize chat request: {0}")]
33    SerializationError(#[from] serde_json::Error),
34
35    #[error("Failed to deserialize response into provider type")]
36    DeserializationError,
37
38    #[error("Failed to extract embedding config. Check provider and config compatibility: {0}")]
39    EmbeddingConfigExtractionError(String),
40
41    #[error("Missing authentication information. Failed to find API_KEY or credentials in environment variables.")]
42    MissingAuthenticationError,
43
44    #[error("Unsupported content type")]
45    UnsupportedContentTypeError,
46
47    #[error("Failed to get response: {0} with status code {1}")]
48    CompletionError(String, StatusCode),
49
50    #[error("Provider not supported: {0}")]
51    ProviderNotSupportedError(String),
52
53    #[error("No provider specified in GenAiClient")]
54    NoProviderError,
55
56    #[error("Undefined error: {0}")]
57    UndefinedError(String),
58
59    #[error("Invalid response type")]
60    InvalidResponseType(String),
61
62    #[error("Failed to create tokio runtime: {0}")]
63    RuntimeError(String),
64
65    #[error("No embeddings found in the response")]
66    NoEmbeddingsFound,
67
68    #[error(transparent)]
69    TypeError(#[from] potato_type::error::TypeError),
70
71    #[error(transparent)]
72    UtilError(#[from] potato_util::UtilError),
73
74    #[error(transparent)]
75    DecodeError(#[from] base64::DecodeError),
76
77    #[error(transparent)]
78    Utf8Error(#[from] std::string::FromUtf8Error),
79
80    #[error(transparent)]
81    GCloudAuthError(#[from] GCloudAuthError),
82
83    #[error("No Google credentials found in environment variables")]
84    NoCredentialsFound,
85
86    #[error("No project ID found in credentials or environment variables")]
87    NoProjectIdFound,
88
89    #[error("Failed to retrieve access token: {0}")]
90    TokenError(String),
91
92    #[error("Failed to retrieve OPENAI_API_KEY from the environment")]
93    MissingOpenAIApiKeyError,
94
95    #[error("{0}")]
96    NotImplementedError(String),
97
98    #[error("Method does not support PredictRequest")]
99    DoesNotSupportPredictRequest,
100
101    #[error("Method does not support array inputs")]
102    DoesNotSupportArray,
103
104    #[error("{0}")]
105    InvalidInputType(String),
106
107    #[error("{0}")]
108    InvalidConfigType(String),
109
110    #[error("Embedding not supported for this provider")]
111    EmbeddingNotSupported,
112
113    #[error(transparent)]
114    MacroError(#[from] potatohead_macro::error::MacroError),
115}
116
117impl<'a, 'py> From<pyo3::CastError<'a, 'py>> for ProviderError {
118    fn from(err: pyo3::CastError<'a, 'py>) -> Self {
119        ProviderError::DowncastError(err.to_string())
120    }
121}
122
123impl From<ProviderError> for PyErr {
124    fn from(err: ProviderError) -> PyErr {
125        let msg = err.to_string();
126        error!("{}", msg);
127        PyRuntimeError::new_err(msg)
128    }
129}
130
131impl From<PyErr> for ProviderError {
132    fn from(err: PyErr) -> Self {
133        ProviderError::Error(err.to_string())
134    }
135}
136
137impl<'a, 'py> From<PyClassGuardError<'a, 'py>> for ProviderError {
138    fn from(err: PyClassGuardError<'a, 'py>) -> Self {
139        ProviderError::Error(err.to_string())
140    }
141}