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)]
22pub enum ProviderError {
23 OpenAI(OpenAIError),
25 Anthropic(AnthropicError),
27 Gemini(GeminiError),
29 Azure(AzureOpenAIError),
31 Cohere(CohereError),
33 Ollama(OllamaError),
35 Assistant(AssistantError),
37 Responses(ResponsesError),
39 DeepSeek(OpenAIError),
41 Qwen(OpenAIError),
43 Moonshot(OpenAIError),
45 Zhipu(OpenAIError),
47 Mistral(OpenAIError),
49}
50
51impl std::fmt::Display for ProviderError {
52 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53 match self {
54 ProviderError::OpenAI(e) => write!(f, "OpenAI error: {e}"),
55 ProviderError::Anthropic(e) => write!(f, "Anthropic error: {e}"),
56 ProviderError::Gemini(e) => write!(f, "Gemini error: {e}"),
57 ProviderError::Azure(e) => write!(f, "Azure OpenAI error: {e}"),
58 ProviderError::Cohere(e) => write!(f, "Cohere error: {e}"),
59 ProviderError::Ollama(e) => write!(f, "Ollama error: {e}"),
60 ProviderError::Assistant(e) => write!(f, "Assistant error: {e}"),
61 ProviderError::Responses(e) => write!(f, "Responses error: {e}"),
62 ProviderError::DeepSeek(e) => write!(f, "DeepSeek error: {e}"),
63 ProviderError::Qwen(e) => write!(f, "Qwen error: {e}"),
64 ProviderError::Moonshot(e) => write!(f, "Moonshot error: {e}"),
65 ProviderError::Zhipu(e) => write!(f, "Zhipu error: {e}"),
66 ProviderError::Mistral(e) => write!(f, "Mistral error: {e}"),
67 }
68 }
69}
70
71impl std::error::Error for ProviderError {
72 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
73 match self {
74 ProviderError::OpenAI(e) => Some(e),
75 ProviderError::Anthropic(e) => Some(e),
76 ProviderError::Gemini(e) => Some(e),
77 ProviderError::Azure(e) => Some(e),
78 ProviderError::Cohere(e) => Some(e),
79 ProviderError::Ollama(e) => Some(e),
80 ProviderError::Assistant(e) => Some(e),
81 ProviderError::Responses(e) => Some(e),
82 ProviderError::DeepSeek(e) => Some(e),
83 ProviderError::Qwen(e) => Some(e),
84 ProviderError::Moonshot(e) => Some(e),
85 ProviderError::Zhipu(e) => Some(e),
86 ProviderError::Mistral(e) => Some(e),
87 }
88 }
89}
90
91impl From<OpenAIError> for ProviderError {
94 fn from(e: OpenAIError) -> Self {
95 ProviderError::OpenAI(e)
96 }
97}
98impl From<AnthropicError> for ProviderError {
99 fn from(e: AnthropicError) -> Self {
100 ProviderError::Anthropic(e)
101 }
102}
103impl From<GeminiError> for ProviderError {
104 fn from(e: GeminiError) -> Self {
105 ProviderError::Gemini(e)
106 }
107}
108impl From<OllamaError> for ProviderError {
109 fn from(e: OllamaError) -> Self {
110 ProviderError::Ollama(e)
111 }
112}
113impl From<AssistantError> for ProviderError {
114 fn from(e: AssistantError) -> Self {
115 ProviderError::Assistant(e)
116 }
117}
118impl From<ResponsesError> for ProviderError {
119 fn from(e: ResponsesError) -> Self {
120 ProviderError::Responses(e)
121 }
122}
123impl From<AzureOpenAIError> for ProviderError {
124 fn from(e: AzureOpenAIError) -> Self {
125 ProviderError::Azure(e)
126 }
127}
128impl From<CohereError> for ProviderError {
129 fn from(e: CohereError) -> Self {
130 ProviderError::Cohere(e)
131 }
132}
133
134impl From<ProviderError> for lc_core::LcelError {
139 fn from(err: ProviderError) -> Self {
140 lc_core::LcelError::Provider(err.to_string())
141 }
142}
143
144impl From<OpenAIError> for lc_core::LcelError {
151 fn from(err: OpenAIError) -> Self {
152 lc_core::LcelError::Provider(err.to_string())
153 }
154}
155
156#[cfg(test)]
157mod tests {
158 use super::*;
159
160 #[test]
162 fn openai_error_into_lcel_error() {
163 let e = OpenAIError::Api("rate limited".to_string());
164 let lcel: lc_core::LcelError = e.into();
165 assert!(matches!(
166 lcel,
167 lc_core::LcelError::Provider(ref msg) if msg.contains("API 错误: rate limited")
168 ));
169 }
170
171 #[test]
173 fn qwen_provider_error_into_lcel_error() {
174 let e = ProviderError::Qwen(OpenAIError::Http("timeout".to_string()));
175 let lcel: lc_core::LcelError = e.into();
176 assert!(matches!(
177 lcel,
178 lc_core::LcelError::Provider(ref msg) if msg.contains("Qwen error") && msg.contains("timeout")
179 ));
180 }
181
182 #[test]
183 fn deepseek_provider_error_into_lcel_error() {
184 let e = ProviderError::DeepSeek(OpenAIError::Parse("bad json".to_string()));
185 let lcel: lc_core::LcelError = e.into();
186 assert!(matches!(
187 lcel,
188 lc_core::LcelError::Provider(ref msg) if msg.contains("DeepSeek error")
189 ));
190 }
191}