1pub use crate::ollama::OllamaError;
8pub use crate::openai::responses::types::ResponsesError;
9pub use crate::openai::AssistantError;
10pub use crate::openai::OpenAIError;
11pub use crate::providers::anthropic::error::AnthropicError;
12pub use crate::providers::azure::AzureOpenAIError;
13pub use crate::providers::cohere::CohereError;
14pub use crate::providers::gemini::GeminiError;
15
16#[derive(Debug)]
22#[non_exhaustive]
23pub enum ProviderError {
24 OpenAI(OpenAIError),
26 Anthropic(AnthropicError),
28 Gemini(GeminiError),
30 Azure(AzureOpenAIError),
32 Cohere(CohereError),
34 Ollama(OllamaError),
36 Assistant(AssistantError),
38 Responses(ResponsesError),
40 DeepSeek(OpenAIError),
42 Qwen(OpenAIError),
44 Moonshot(OpenAIError),
46 Zhipu(OpenAIError),
48 Mistral(OpenAIError),
50 Config(String),
52 Testkit(String),
54}
55
56impl std::fmt::Display for ProviderError {
57 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58 match self {
59 ProviderError::OpenAI(e) => write!(f, "OpenAI error: {e}"),
60 ProviderError::Anthropic(e) => write!(f, "Anthropic error: {e}"),
61 ProviderError::Gemini(e) => write!(f, "Gemini error: {e}"),
62 ProviderError::Azure(e) => write!(f, "Azure OpenAI error: {e}"),
63 ProviderError::Cohere(e) => write!(f, "Cohere error: {e}"),
64 ProviderError::Ollama(e) => write!(f, "Ollama error: {e}"),
65 ProviderError::Assistant(e) => write!(f, "Assistant error: {e}"),
66 ProviderError::Responses(e) => write!(f, "Responses error: {e}"),
67 ProviderError::DeepSeek(e) => write!(f, "DeepSeek error: {e}"),
68 ProviderError::Qwen(e) => write!(f, "Qwen error: {e}"),
69 ProviderError::Moonshot(e) => write!(f, "Moonshot error: {e}"),
70 ProviderError::Zhipu(e) => write!(f, "Zhipu error: {e}"),
71 ProviderError::Mistral(e) => write!(f, "Mistral error: {e}"),
72 ProviderError::Config(msg) => write!(f, "Configuration error: {msg}"),
73 ProviderError::Testkit(msg) => write!(f, "Testkit error: {msg}"),
74 }
75 }
76}
77
78impl std::error::Error for ProviderError {
79 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
80 match self {
81 ProviderError::OpenAI(e) => Some(e),
82 ProviderError::Anthropic(e) => Some(e),
83 ProviderError::Gemini(e) => Some(e),
84 ProviderError::Azure(e) => Some(e),
85 ProviderError::Cohere(e) => Some(e),
86 ProviderError::Ollama(e) => Some(e),
87 ProviderError::Assistant(e) => Some(e),
88 ProviderError::Responses(e) => Some(e),
89 ProviderError::DeepSeek(e) => Some(e),
90 ProviderError::Qwen(e) => Some(e),
91 ProviderError::Moonshot(e) => Some(e),
92 ProviderError::Zhipu(e) => Some(e),
93 ProviderError::Mistral(e) => Some(e),
94 ProviderError::Config(_) => None,
95 ProviderError::Testkit(_) => None,
96 }
97 }
98}
99
100impl From<OpenAIError> for ProviderError {
103 fn from(e: OpenAIError) -> Self {
104 ProviderError::OpenAI(e)
105 }
106}
107impl From<AnthropicError> for ProviderError {
108 fn from(e: AnthropicError) -> Self {
109 ProviderError::Anthropic(e)
110 }
111}
112impl From<GeminiError> for ProviderError {
113 fn from(e: GeminiError) -> Self {
114 ProviderError::Gemini(e)
115 }
116}
117impl From<OllamaError> for ProviderError {
118 fn from(e: OllamaError) -> Self {
119 ProviderError::Ollama(e)
120 }
121}
122impl From<AssistantError> for ProviderError {
123 fn from(e: AssistantError) -> Self {
124 ProviderError::Assistant(e)
125 }
126}
127impl From<ResponsesError> for ProviderError {
128 fn from(e: ResponsesError) -> Self {
129 ProviderError::Responses(e)
130 }
131}
132impl From<AzureOpenAIError> for ProviderError {
133 fn from(e: AzureOpenAIError) -> Self {
134 ProviderError::Azure(e)
135 }
136}
137impl From<CohereError> for ProviderError {
138 fn from(e: CohereError) -> Self {
139 ProviderError::Cohere(e)
140 }
141}
142
143impl From<String> for ProviderError {
147 fn from(msg: String) -> Self {
148 ProviderError::Testkit(msg)
149 }
150}
151
152impl From<ProviderError> for lc_core::LcelError {
157 fn from(err: ProviderError) -> Self {
158 lc_core::LcelError::Provider(err.to_string())
159 }
160}
161
162impl From<OpenAIError> for lc_core::LcelError {
169 fn from(err: OpenAIError) -> Self {
170 lc_core::LcelError::Provider(err.to_string())
171 }
172}
173
174#[cfg(test)]
175mod tests {
176 use super::*;
177
178 #[test]
180 fn openai_error_into_lcel_error() {
181 let e = OpenAIError::Api("rate limited".to_string());
182 let lcel: lc_core::LcelError = e.into();
183 assert!(matches!(
184 lcel,
185 lc_core::LcelError::Provider(ref msg) if msg.contains("API error: rate limited")
186 ));
187 }
188
189 #[test]
191 fn qwen_provider_error_into_lcel_error() {
192 let e = ProviderError::Qwen(OpenAIError::Http("timeout".to_string()));
193 let lcel: lc_core::LcelError = e.into();
194 assert!(matches!(
195 lcel,
196 lc_core::LcelError::Provider(ref msg) if msg.contains("Qwen error") && msg.contains("timeout")
197 ));
198 }
199
200 #[test]
201 fn deepseek_provider_error_into_lcel_error() {
202 let e = ProviderError::DeepSeek(OpenAIError::Parse("bad json".to_string()));
203 let lcel: lc_core::LcelError = e.into();
204 assert!(matches!(
205 lcel,
206 lc_core::LcelError::Provider(ref msg) if msg.contains("DeepSeek error")
207 ));
208 }
209}