fix(frontend): return 4xx for Backend(InvalidArgument) on streaming c… - #12036
Conversation
|
👋 Hi ritazh! Thank you for contributing to ai-dynamo/dynamo. Just a reminder: The 🚀 |
718b7d8 to
82d9a9d
Compare
82d9a9d to
def76c9
Compare
WalkthroughStreaming chat-completions and responses handlers now inspect initial backend stream events before committing HTTP 200, returning typed HTTP errors for synchronous backend failures while preserving existing SSE behavior. ChangesStreaming error handling
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
lib/llm/src/http/service/openai.rs (4)
1965-1982: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd a regression test for the reported repro.
The PR fixes a concrete repro (text-only model +
image_urlcontent +stream: true→ should be 4xx, not 200+500-SSE). Since this file review doesn't show a corresponding test update, consider adding one covering the streaming chat-completions path specifically (in addition to any responses-endpoint equivalent).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/llm/src/http/service/openai.rs` around lines 1965 - 1982, Add a regression test for the streaming chat-completions path covering a text-only model receiving image_url content with stream enabled. Assert that the request returns the expected 4xx status and typed backend error response rather than HTTP 200 followed by a generic 500 SSE frame, using the existing test helpers and conventions.
1965-1982: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicated arm+check+log+mark_error pattern.
This block (arm →
check_for_backend_error→tracing::error!→mark_error) is now duplicated in the responses-streaming branch (lines 2457-2471) and mirrors the pre-existing non-streaming blocks (2050-2058, 2541-2549). Consider extracting a small shared helper to keep the 4xx/5xx-preserving contract consistent as this logic evolves.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/llm/src/http/service/openai.rs` around lines 1965 - 1982, The arm, backend-error check, logging, and inflight error marking are duplicated across streaming and non-streaming response paths. Extract this sequence into a small shared helper, then use it from the affected branches around check_for_backend_error while preserving the existing typed error response and HTTP status behavior.
2457-2471: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winSame test-coverage suggestion as the chat-completions streaming branch.
A regression test for the Responses streaming endpoint (image content vs text-only model,
stream: true) would complement the one suggested at lines 1965-1982; see consolidated comment.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/llm/src/http/service/openai.rs` around lines 2457 - 2471, Add a regression test for the Responses streaming endpoint covering an image-content request sent to a text-only model with stream: true, and assert it returns the expected typed 4xx backend error before committing HTTP 200. Place it alongside the existing streaming error tests and mirror the chat-completions coverage pattern referenced by check_for_backend_error.
2457-2471: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winSame duplicated pattern as the chat-completions streaming branch.
Mirrors the arm+check+log+mark_error duplication flagged at lines 1965-1982; see consolidated comment.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/llm/src/http/service/openai.rs` around lines 2457 - 2471, The streaming branch duplicates the arm, backend-error check, logging, and inflight error-marking logic already used by the chat-completions path. Consolidate this flow into the shared helper or abstraction introduced for that pattern, updating the code around engine_stream and preserving client-disconnect handling, typed error responses, tracing, and mark_error behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/llm/src/http/service/openai.rs`:
- Around line 1965-1982: Wrap the check_for_backend_error(stream).await call in
the streaming setup with a bounded tokio::time::timeout so a stalled backend
cannot hold the request or permit indefinitely before HTTP 200. Preserve the
existing tracing, inflight_guard.mark_error, and err_response propagation for
backend errors, and map timeout expiration through the route’s established error
response path.
---
Nitpick comments:
In `@lib/llm/src/http/service/openai.rs`:
- Around line 1965-1982: Add a regression test for the streaming
chat-completions path covering a text-only model receiving image_url content
with stream enabled. Assert that the request returns the expected 4xx status and
typed backend error response rather than HTTP 200 followed by a generic 500 SSE
frame, using the existing test helpers and conventions.
- Around line 1965-1982: The arm, backend-error check, logging, and inflight
error marking are duplicated across streaming and non-streaming response paths.
Extract this sequence into a small shared helper, then use it from the affected
branches around check_for_backend_error while preserving the existing typed
error response and HTTP status behavior.
- Around line 2457-2471: Add a regression test for the Responses streaming
endpoint covering an image-content request sent to a text-only model with
stream: true, and assert it returns the expected typed 4xx backend error before
committing HTTP 200. Place it alongside the existing streaming error tests and
mirror the chat-completions coverage pattern referenced by
check_for_backend_error.
- Around line 2457-2471: The streaming branch duplicates the arm, backend-error
check, logging, and inflight error-marking logic already used by the
chat-completions path. Consolidate this flow into the shared helper or
abstraction introduced for that pattern, updating the code around engine_stream
and preserving client-disconnect handling, typed error responses, tracing, and
mark_error behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 1eb19b42-9872-4a0d-a865-1150898577f2
📒 Files selected for processing (1)
lib/llm/src/http/service/openai.rs
|
🎯 Code Coverage (details) 🔗 Commit SHA: 0f6f60a | Docs | Datadog PR Page | Give us feedback! |
|
Hi @ritazh, thanks for the contribution!
|
cf64d36 to
59adeaf
Compare
|
Addressed review comments:
|
…hat/responses Signed-off-by: Rita Zhang <1856066+ritazh@users.noreply.github.com>
65e0731 to
b29377d
Compare
|
/ok to test b29377d |
Signed-off-by: Rita Zhang <1856066+ritazh@users.noreply.github.com>
a8a36a5 to
8772a78
Compare
bec5ad5 to
754f372
Compare
Signed-off-by: Rita Zhang <1856066+ritazh@users.noreply.github.com>
754f372 to
73234e0
Compare
|
@GuanLuo addressed your nits. PTAL. Good to merge? |
|
/ok to test 0f6f60a |
…hat/responses
Overview:
A /v1/chat/completions or /v1/responses request with
stream: truethat hits a synchronous backend InvalidArgument at request-parse time (before any token is generated) currently emits:The identical request with
stream: falsecorrectly returns HTTP 400 with the typed message, because the non-streaming branch already callscheck_for_backend_error()before folding the stream for chat_completions and responses. The streaming branches skip this check and rely onmonitor_for_disconnects_with_timeout(), which hardcodesSanitizedError::Internalfor any Err and loses theBackend(InvalidArgument)classification.Reproducible with zai-org/GLM-5.2 (text-only) + image_url content +
stream: true: the model correctly refuses (ValueError: Received multimodal data but multimodal processing is not enabled), then returns Backend(InvalidArgument), but the streaming SSE frame still surfacescode: 500.Details:
Where should the reviewer start?
Related Issues
🔗 This PR is linked to an issue:
🚫 This PR is NOT linked to an issue:
Summary by CodeRabbit