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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
//! HTTP client error types with comprehensive retry detection.
//!
//! This module provides error types for HTTP operations with built-in support for
//! retry detection, error categorization, and detailed error information.
//!
//! # Overview
//!
//! The [`HttpError`] enum covers all possible failure modes for HTTP requests:
//! - Network errors (connection failures, DNS issues)
//! - HTTP errors (4xx client errors, 5xx server errors)
//! - Serialization/deserialization errors
//! - Authentication errors
//! - Timeouts
//! - Configuration errors
//!
//! # Retry Detection
//!
//! The error type includes built-in retry detection via [`HttpError::is_retryable()`]:
//! - Network errors → retryable
//! - Timeouts → retryable
//! - 429 (rate limit) → retryable
//! - 500, 502, 503, 504 (server errors) → retryable
//! - All other errors → not retryable
//!
//! When using the generated HTTP client with retry middleware (reqwest-retry),
//! retryable errors are automatically retried with exponential backoff.
//!
//! # Examples
//!
//! ## Basic Error Handling
//!
//! ```
//! # use openapi_to_rust::http_error::HttpError;
//! fn handle_api_error(error: HttpError) {
//! match error {
//! HttpError::Network(e) => {
//! eprintln!("Network error: {}", e);
//! // Will be retried automatically if retry is configured
//! }
//! HttpError::Http { status, message, .. } => {
//! match status {
//! 400 => eprintln!("Bad request: {}", message),
//! 401 => eprintln!("Unauthorized - check API key"),
//! 404 => eprintln!("Not found"),
//! 429 => eprintln!("Rate limited - will retry"),
//! 500..=599 => eprintln!("Server error: {}", message),
//! _ => eprintln!("HTTP error {}: {}", status, message),
//! }
//! }
//! HttpError::Timeout => {
//! eprintln!("Request timeout - will retry");
//! }
//! e => {
//! eprintln!("Other error: {}", e);
//! }
//! }
//! }
//! ```
//!
//! ## Retry Detection
//!
//! ```
//! # use openapi_to_rust::http_error::HttpError;
//! fn classify_error(error: &HttpError) {
//! if error.is_retryable() {
//! println!("Retryable error: {}", error);
//! // If retry middleware is configured, this will be retried automatically
//! } else if error.is_client_error() {
//! println!("Client error (4xx): fix the request");
//! } else if error.is_server_error() {
//! println!("Server error (5xx): may be transient");
//! } else {
//! println!("Non-retryable error: {}", error);
//! }
//! }
//! ```
//!
//! ## Creating Errors
//!
//! ```
//! use openapi_to_rust::http_error::HttpError;
//!
//! // Create HTTP error from status code
//! let error = HttpError::from_status(404, "Resource not found", None);
//!
//! // Create serialization error
//! let error = HttpError::serialization_error("invalid JSON");
//!
//! // Create deserialization error
//! let error = HttpError::deserialization_error("unexpected field");
//! ```
//!
//! # Integration with reqwest-retry
//!
//! When the generated HTTP client is configured with retry middleware,
//! the retry logic automatically handles retryable errors:
//!
//! ```toml
//! [http_client.retry]
//! max_retries = 3
//! initial_delay_ms = 500
//! max_delay_ms = 16000
//! ```
//!
//! The retry middleware uses exponential backoff and will retry:
//! - Network errors (connection failures)
//! - Timeouts
//! - HTTP 429 (rate limit)
//! - HTTP 500, 502, 503, 504 (server errors)
//!
//! # Error Categories
//!
//! Errors can be categorized using helper methods:
//! - [`HttpError::is_retryable()`] - Should this error be retried?
//! - [`HttpError::is_client_error()`] - Is this a 4xx error?
//! - [`HttpError::is_server_error()`] - Is this a 5xx error?
use Error;
/// HTTP client errors that can occur during API requests
/// Result type for HTTP operations
pub type HttpResult<T> = ;
/// Envelope for an API response we received but couldn't (or didn't) treat as success.
///
/// `ApiError<E>` is returned whenever the server actually responded — whether the
/// status was non-2xx, or the 2xx body failed to deserialize into the expected
/// type. `status`, `headers`, and `body` are always populated so callers can
/// inspect what the server actually sent without having to hack the generated
/// client. `typed` is `Some(_)` when the raw body was successfully parsed into a
/// per-operation error type; `parse_error` records why parsing failed when not.
/// Result error type for generated operation methods.
///
/// `Transport` covers failures where the request never produced a response we
/// can inspect (network, timeout, middleware, request-side serialization).
/// `Api` covers any case where the server *did* respond — the envelope always
/// carries status + headers + raw body even when the typed deserialize fails.