fix: detect raw JSON errors in streaming path

When a provider returns a JSON error (e.g., {"error":{"message":"..."}})
without SSE framing (no "data:" prefix), the SSE parser was silently
ignoring it and hanging. Now detects and surfaces these errors.

Also handles HTML responses that lack SSE framing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
TheArchitectit
2026-04-29 20:46:32 -05:00
committed by Independent Security Research
parent baa8d1ba6e
commit 33d2f7892d

View File

@@ -1521,6 +1521,7 @@ fn parse_sse_frame(
body: trimmed.chars().take(500).collect(),
retryable: false,
suggested_action: suggested_action_for_status(status),
retry_after: None,
});
}
}
@@ -1536,6 +1537,7 @@ fn parse_sse_frame(
body: trimmed.chars().take(200).collect(),
retryable: false,
suggested_action: Some("verify the API endpoint URL is correct".to_string()),
retry_after: None,
});
}
return Ok(None);
@@ -1575,22 +1577,6 @@ fn parse_sse_frame(
});
}
}
// Detect HTML or other non-JSON responses early for better error messages
let trimmed_payload = payload.trim();
if trimmed_payload.starts_with('<') || trimmed_payload.starts_with("<!") {
return Err(ApiError::Api {
status: reqwest::StatusCode::BAD_REQUEST,
error_type: Some("invalid_response".to_string()),
message: Some(
"provider returned HTML instead of JSON (check endpoint URL)".to_string(),
),
request_id: None,
body: payload.chars().take(200).collect(),
retryable: false,
suggested_action: Some("verify the API endpoint URL is correct".to_string()),
retry_after: None,
});
}
serde_json::from_str::<ChatCompletionChunk>(&payload)
.map(Some)
.map_err(|error| ApiError::json_deserialize(provider, model, &payload, error))