fix(ai): handle non-JSON error response in AI connection test

Replace res.json() with res.text() + fallback JSON parse so that
non-JSON error bodies (e.g. HTTP 502 with empty body) no longer
produce the unclear 'error decoding response body' message.

Also add 502/503/504 to classify_error for proper category prefixes.
This commit is contained in:
lexmin0412 2026-06-23 12:04:46 +08:00 committed by GitHub
parent 3a25487dea
commit c026647785
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 21 additions and 4 deletions

View File

@ -964,8 +964,20 @@ pub async fn test_connection_core(config: &AiConfig) -> Result<AiTestConnectionR
.await
.map_err(|e| format!("AI request failed: {e}"))?;
if !res.status().is_success() {
let data: serde_json::Value = res.json().await.map_err(|e| e.to_string())?;
return Err(categorize_error(&data, config));
let status = res.status();
let body = res.text().await.unwrap_or_default();
// Try JSON first (APIs like OpenAI return structured error bodies)
if let Ok(data) = serde_json::from_str::<serde_json::Value>(&body) {
let raw = extract_error(&data).unwrap_or_else(|| "API error".to_string());
return Err(format!("[{}] {}", classify_error(&raw), raw));
}
// Non-JSON body — show HTTP status + raw body
let msg = if body.trim().is_empty() {
format!("HTTP {}", status)
} else {
format!("HTTP {}: {}", status, body.trim())
};
return Err(format!("[{}] {}", classify_error(&msg), msg));
}
res.bytes_stream()
}
@ -1005,9 +1017,14 @@ fn classify_error(msg: &str) -> &'static str {
"modelNotFound"
} else if lower.contains("429") || lower.contains("rate limit") || lower.contains("too many requests") {
"rateLimit"
} else if lower.contains("timeout") || lower.contains("timed out") {
} else if lower.contains("timeout") || lower.contains("timed out") || lower.contains("504") {
"timeout"
} else if lower.contains("connect") || lower.contains("dns") || lower.contains("resolve") {
} else if lower.contains("connect")
|| lower.contains("dns")
|| lower.contains("resolve")
|| lower.contains("502")
|| lower.contains("503")
{
"network"
} else {
"unknown"