|
2 | 2 | //! |
3 | 3 | //! Single HTTP provider (OpenRouter default). No streaming; minimal types. |
4 | 4 |
|
| 5 | +use std::error::Error; |
5 | 6 | use std::time::Duration; |
6 | 7 |
|
7 | 8 | use serde::{Deserialize, Serialize}; |
@@ -116,6 +117,32 @@ impl std::fmt::Display for LlmError { |
116 | 117 |
|
117 | 118 | impl std::error::Error for LlmError {} |
118 | 119 |
|
| 120 | +/// Format a reqwest error with an explicit kind/code (timeout, connection, HTTP status) and the full |
| 121 | +/// error chain, so users see what actually happened. |
| 122 | +fn format_reqwest_error(e: &reqwest::Error) -> String { |
| 123 | + let code = if let Some(status) = e.status() { |
| 124 | + format!( |
| 125 | + "HTTP {} {}", |
| 126 | + status.as_u16(), |
| 127 | + status.canonical_reason().unwrap_or("") |
| 128 | + ) |
| 129 | + } else if e.is_timeout() { |
| 130 | + "timeout".to_string() |
| 131 | + } else if e.is_connect() { |
| 132 | + "connection failed".to_string() |
| 133 | + } else { |
| 134 | + "request failed".to_string() |
| 135 | + }; |
| 136 | + let mut detail = e.to_string(); |
| 137 | + let mut src: Option<&(dyn Error + '_)> = e.source(); |
| 138 | + while let Some(inner) = src { |
| 139 | + detail.push_str(" | "); |
| 140 | + detail.push_str(&inner.to_string()); |
| 141 | + src = inner.source(); |
| 142 | + } |
| 143 | + format!("{} | {}", code, detail) |
| 144 | +} |
| 145 | + |
119 | 146 | // --- Request/response (raw API shape for serde) --- |
120 | 147 |
|
121 | 148 | #[derive(Serialize)] |
@@ -235,13 +262,13 @@ impl HttpProvider { |
235 | 262 | .json(&body) |
236 | 263 | .send() |
237 | 264 | .await |
238 | | - .map_err(|e| LlmError::Http(e.to_string()))?; |
| 265 | + .map_err(|e| LlmError::Http(format_reqwest_error(&e)))?; |
239 | 266 |
|
240 | 267 | let status = res.status(); |
241 | 268 | let text = res |
242 | 269 | .text() |
243 | 270 | .await |
244 | | - .map_err(|e| LlmError::Http(e.to_string()))?; |
| 271 | + .map_err(|e| LlmError::Http(format_reqwest_error(&e)))?; |
245 | 272 | if !status.is_success() { |
246 | 273 | return Err(LlmError::Http(format!("{} {}", status, text))); |
247 | 274 | } |
|
0 commit comments