hehe_llm/
error.rs

1use hehe_core::error::Error as CoreError;
2use thiserror::Error;
3
4#[derive(Error, Debug)]
5pub enum LlmError {
6    #[error("API error: {provider} - {message}")]
7    Api { provider: String, message: String },
8
9    #[error("Rate limited: {provider}, retry after {retry_after_ms:?}ms")]
10    RateLimited {
11        provider: String,
12        retry_after_ms: Option<u64>,
13    },
14
15    #[error("Context length exceeded: {max_tokens} tokens maximum")]
16    ContextLengthExceeded { max_tokens: u32 },
17
18    #[error("Invalid request: {0}")]
19    InvalidRequest(String),
20
21    #[error("Invalid response: {0}")]
22    InvalidResponse(String),
23
24    #[error("Model not found: {0}")]
25    ModelNotFound(String),
26
27    #[error("Authentication failed: {0}")]
28    AuthenticationFailed(String),
29
30    #[error("Network error: {0}")]
31    Network(String),
32
33    #[error("Timeout after {0}ms")]
34    Timeout(u64),
35
36    #[error("Stream error: {0}")]
37    Stream(String),
38
39    #[error("Provider not available: {0}")]
40    ProviderNotAvailable(String),
41
42    #[error("Tool error: {0}")]
43    Tool(String),
44
45    #[error("Configuration error: {0}")]
46    Config(String),
47
48    #[error(transparent)]
49    Core(#[from] CoreError),
50
51    #[error(transparent)]
52    Reqwest(#[from] reqwest::Error),
53
54    #[error(transparent)]
55    Json(#[from] serde_json::Error),
56}
57
58pub type Result<T> = std::result::Result<T, LlmError>;
59
60impl LlmError {
61    pub fn api(provider: impl Into<String>, message: impl Into<String>) -> Self {
62        Self::Api {
63            provider: provider.into(),
64            message: message.into(),
65        }
66    }
67
68    pub fn rate_limited(provider: impl Into<String>, retry_after_ms: Option<u64>) -> Self {
69        Self::RateLimited {
70            provider: provider.into(),
71            retry_after_ms,
72        }
73    }
74
75    pub fn invalid_request(msg: impl Into<String>) -> Self {
76        Self::InvalidRequest(msg.into())
77    }
78
79    pub fn invalid_response(msg: impl Into<String>) -> Self {
80        Self::InvalidResponse(msg.into())
81    }
82
83    pub fn network(msg: impl Into<String>) -> Self {
84        Self::Network(msg.into())
85    }
86
87    pub fn stream(msg: impl Into<String>) -> Self {
88        Self::Stream(msg.into())
89    }
90
91    pub fn is_retryable(&self) -> bool {
92        matches!(
93            self,
94            LlmError::RateLimited { .. } | LlmError::Timeout(_) | LlmError::Network(_)
95        )
96    }
97}