Skip to main content

lc_providers/
error.rs

1// lc-providers/src/error.rs
2//! Unified error type for the lc-providers crate.
3//!
4//! Aggregates all provider-specific error types so the `?` operator works
5//! seamlessly across provider boundaries.
6
7pub 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/// Unified error type that aggregates all LLM provider errors.
17///
18/// This allows using `?` across provider boundaries without manually
19/// mapping error types. Each variant wraps the original provider
20/// error, preserving full context.
21#[derive(Debug)]
22pub enum ProviderError {
23    /// OpenAI API error.
24    OpenAI(OpenAIError),
25    /// Anthropic API error.
26    Anthropic(AnthropicError),
27    /// Gemini API error.
28    Gemini(GeminiError),
29    /// Azure OpenAI API error.
30    Azure(AzureOpenAIError),
31    /// Cohere API error.
32    Cohere(CohereError),
33    /// Ollama API error.
34    Ollama(OllamaError),
35    /// OpenAI Assistants API error.
36    Assistant(AssistantError),
37    /// OpenAI Responses API error.
38    Responses(ResponsesError),
39    /// DeepSeek API error (OpenAI-compatible endpoint).
40    DeepSeek(OpenAIError),
41    /// Qwen (Alibaba) API error (OpenAI-compatible endpoint).
42    Qwen(OpenAIError),
43    /// Moonshot (Kimi) API error (OpenAI-compatible endpoint).
44    Moonshot(OpenAIError),
45    /// Zhipu (ChatGLM) API error (OpenAI-compatible endpoint).
46    Zhipu(OpenAIError),
47    /// Mistral API error (OpenAI-compatible endpoint).
48    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
91// ---- From impls for all provider error types ----
92
93impl 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
134// ---- LCEL Error conversion ----
135
136/// Allow `ProviderError` to convert into `LcelError` for LCEL pipeline compatibility.
137/// This enables LLM providers to participate in `pipe()` chains.
138impl From<ProviderError> for lc_core::LcelError {
139    fn from(err: ProviderError) -> Self {
140        lc_core::LcelError::Provider(err.to_string())
141    }
142}