1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
mod private
{
use error_tools::dependency::thiserror;
/// Error types for XAI API operations.
///
/// This enum covers all possible error conditions when interacting with the XAI API,
/// including network errors, API errors, serialization issues, and configuration problems.
///
/// # Error Categories
///
/// - **API Errors**: Errors returned by the XAI API itself
/// - **HTTP Errors**: Generic HTTP-level failures
/// - **Network Errors**: Connection and transport issues
/// - **Timeout Errors**: Request timeout conditions
/// - **Stream Errors**: SSE streaming failures
/// - **Rate Limit Errors**: API rate limiting
/// - **Serialization Errors**: JSON parsing failures
/// - **Authentication Errors**: Invalid API key or credentials
/// - **Environment Errors**: Configuration and setup issues
#[ derive( Debug, Clone, PartialEq, thiserror::Error ) ]
#[ non_exhaustive ]
pub enum XaiError
{
/// API error returned by XAI service.
///
/// Contains structured error information including message, error code,
/// and error type from the API response.
#[ error( "API Error : {message} (code : {code:?}, type : {error_type:?})" ) ]
Api
{
/// Human-readable error message
message : String,
/// Error code (e.g., `"invalid_request_error"`)
code : Option< String >,
/// Error type classification
error_type : Option< String >,
},
/// HTTP-level error.
///
/// Generic HTTP failures that dont fit into more specific categories.
#[ error( "HTTP Error : {0}" ) ]
Http( String ),
/// Network connectivity error.
///
/// Connection failures, DNS resolution errors, or other transport-level issues.
#[ error( "Network Error : {0}" ) ]
Network( String ),
/// Request timeout error.
///
/// The request exceeded the configured timeout duration.
#[ error( "Timeout Error : {0}" ) ]
Timeout( String ),
/// SSE streaming error.
///
/// Failures during Server-Sent Events streaming, including parse errors
/// and connection interruptions.
#[ error( "Stream Error : {0}" ) ]
Stream( String ),
/// Rate limit exceeded error.
///
/// The API returned a 429 status indicating rate limiting is active.
/// Client should implement exponential backoff.
#[ error( "Rate Limit Error : {0}" ) ]
RateLimit( String ),
/// Serialization or deserialization error.
///
/// JSON parsing failures or serialization issues with request/response data.
#[ error( "Serialization Error : {0}" ) ]
Serialization( String ),
/// Invalid API key error.
///
/// The provided API key is malformed or doesn't meet validation requirements.
#[ error( "Invalid API Key : {0}" ) ]
InvalidApiKey( String ),
/// Environment configuration error.
///
/// Issues with environment setup, missing variables, or invalid configuration.
#[ error( "Environment Error : {0}" ) ]
Environment( String ),
/// URL parsing error.
///
/// Invalid URL format in configuration or endpoint construction.
#[ error( "URL Parse Error : {0}" ) ]
UrlParse( String ),
/// Circuit breaker open error.
///
/// The circuit breaker is in open state, preventing requests to a failing endpoint.
#[ cfg( feature = "circuit_breaker" ) ]
#[ error( "Circuit Breaker Open : {0}" ) ]
CircuitBreakerOpen( String ),
/// Invalid model error.
///
/// The specified model name is not recognized or supported.
#[ error( "Invalid Model : {0}" ) ]
InvalidModel( String ),
/// Invalid parameter error.
///
/// Request parameter validation failed.
#[ error( "Invalid Parameter : {0}" ) ]
InvalidParameter( String ),
/// Generic API error.
///
/// Catch-all for API-related errors that dont fit other categories.
#[ error( "API Error : {0}" ) ]
ApiError( String ),
}
/// Result type alias using `error_tools`.
///
/// This is the standard Result type used throughout the `api_xai` crate.
/// All fallible operations return this type.
pub type Result< T > = error_tools::untyped::Result< T >;
// Conversion from reqwest errors
impl From< reqwest::Error > for XaiError
{
fn from( error : reqwest::Error ) -> Self
{
if error.is_timeout()
{
XaiError::Timeout( error.to_string() )
}
else if error.is_connect() || error.is_request()
{
XaiError::Network( error.to_string() )
}
else if error.is_status()
{
if let Some( status ) = error.status()
{
if status.as_u16() == 429
{
return XaiError::RateLimit( format!( "Rate limit exceeded : {status}" ) );
}
}
XaiError::Http( error.to_string() )
}
else
{
XaiError::Http( error.to_string() )
}
}
}
// Conversion from serde_json errors
impl From< serde_json::Error > for XaiError
{
fn from( error : serde_json::Error ) -> Self
{
XaiError::Serialization( error.to_string() )
}
}
// Conversion from URL parse errors
impl From< url::ParseError > for XaiError
{
fn from( error : url::ParseError ) -> Self
{
XaiError::UrlParse( error.to_string() )
}
}
// Conversion from reqwest header value errors
impl From< reqwest::header::InvalidHeaderValue > for XaiError
{
fn from( error : reqwest::header::InvalidHeaderValue ) -> Self
{
XaiError::Http( format!( "Invalid header value : {error}" ) )
}
}
}
crate::mod_interface!
{
exposed use
{
XaiError,
Result,
};
}