1#[derive(Debug, thiserror::Error)]
5pub enum AiError {
6 #[error("Provider error: {0}")]
8 Provider(String),
9
10 #[error("Network error: {0}")]
12 Network(#[from] reqwest::Error),
13
14 #[error("Serialization error: {0}")]
16 Serialization(#[from] serde_json::Error),
17
18 #[error("Authentication error: {0}")]
20 Authentication(String),
21
22 #[error("Rate limit exceeded: {0}")]
24 RateLimit(String),
25
26 #[error("Invalid request: {0}")]
28 InvalidRequest(String),
29
30 #[error("Model not found: {0}")]
32 ModelNotFound(String),
33
34 #[error("Request timeout: {0}")]
36 Timeout(String),
37
38 #[error("Plugin error ({plugin}): {message}")]
40 Plugin { plugin: String, message: String },
41
42 #[error("Layer error ({layer}): {message}")]
44 Layer { layer: String, message: String },
45
46 #[error("Configuration error: {0}")]
48 Configuration(String),
49
50 #[error("Stream error: {0}")]
52 Stream(String),
53
54 #[error("Unsupported operation: {0}")]
56 Unsupported(String),
57
58 #[error("Error: {0}")]
60 Other(String),
61}
62
63impl AiError {
64 pub fn provider(msg: impl Into<String>) -> Self {
66 Self::Provider(msg.into())
67 }
68
69 pub fn authentication(msg: impl Into<String>) -> Self {
71 Self::Authentication(msg.into())
72 }
73
74 pub fn rate_limit(msg: impl Into<String>) -> Self {
76 Self::RateLimit(msg.into())
77 }
78
79 pub fn invalid_request(msg: impl Into<String>) -> Self {
81 Self::InvalidRequest(msg.into())
82 }
83
84 pub fn model_not_found(msg: impl Into<String>) -> Self {
86 Self::ModelNotFound(msg.into())
87 }
88
89 pub fn timeout(msg: impl Into<String>) -> Self {
91 Self::Timeout(msg.into())
92 }
93
94 pub fn plugin(plugin: impl Into<String>, message: impl Into<String>) -> Self {
96 Self::Plugin {
97 plugin: plugin.into(),
98 message: message.into(),
99 }
100 }
101
102 pub fn layer(layer: impl Into<String>, message: impl Into<String>) -> Self {
104 Self::Layer {
105 layer: layer.into(),
106 message: message.into(),
107 }
108 }
109
110 pub fn configuration(msg: impl Into<String>) -> Self {
112 Self::Configuration(msg.into())
113 }
114
115 pub fn stream(msg: impl Into<String>) -> Self {
117 Self::Stream(msg.into())
118 }
119
120 pub fn unsupported(msg: impl Into<String>) -> Self {
122 Self::Unsupported(msg.into())
123 }
124
125 pub fn other(msg: impl Into<String>) -> Self {
127 Self::Other(msg.into())
128 }
129
130 pub fn is_retryable(&self) -> bool {
132 matches!(
133 self,
134 AiError::Network(_) | AiError::Timeout(_) | AiError::RateLimit(_)
135 )
136 }
137}
138
139impl From<String> for AiError {
140 fn from(s: String) -> Self {
141 Self::Other(s)
142 }
143}
144
145impl From<&str> for AiError {
146 fn from(s: &str) -> Self {
147 Self::Other(s.to_string())
148 }
149}