fix(gemini): handle 'Stream ended' gracefully and improve debug logging
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled

This commit is contained in:
2026-03-05 17:34:40 +00:00
parent e307ecf11d
commit 811885274b

View File

@@ -848,11 +848,12 @@ impl super::Provider for GeminiProvider {
let gemini_response: GeminiStreamResponse = serde_json::from_str(&msg.data)
.map_err(|e| AppError::ProviderError(format!("Failed to parse stream chunk: {}", e)))?;
tracing::info!("Received Gemini stream chunk (candidates: {}, has_usage: {})",
tracing::info!("Received Gemini stream chunk (candidates: {}, has_usage: {}, finish_reason: {:?})",
gemini_response.candidates.len(),
gemini_response.usage_metadata.is_some()
gemini_response.usage_metadata.is_some(),
gemini_response.candidates.first().and_then(|c| c.finish_reason.as_deref())
);
// Extract usage from usageMetadata if present (reported on every/last chunk)
let stream_usage = gemini_response.usage_metadata.as_ref().map(|u| {
super::StreamUsage {
@@ -967,6 +968,12 @@ impl super::Provider for GeminiProvider {
}
Ok(_) => continue,
Err(e) => {
// "Stream ended" is usually a normal EOF signal in reqwest-eventsource.
// We check the string representation to avoid returning it as an error.
if e.to_string().contains("Stream ended") {
break;
}
// On stream error, attempt to probe for the actual error body from the provider
let probe_resp = probe_client
.post(&probe_url)