-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
fix(cloudflare): Keep http root span alive until streaming responses are consumed #18087
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
e7d2476 to
b9d02cf
Compare
size-limit report 📦
|
2875b4f to
eb7a5c1
Compare
node-overhead report 🧳Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.
|
febee8b to
fadd2eb
Compare
d729aae to
31ecf58
Compare
| const result = await reader.read(); | ||
| done = result.done; | ||
| } | ||
| } catch { | ||
| // Stream error or cancellation - will end span in finally | ||
| } finally { | ||
| reader.releaseLock(); | ||
| span.end(); | ||
| waitUntil?.(flush(2000)); | ||
| } | ||
| })(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Missing error handling for response.body.tee() call.
Severity: MEDIUM | Confidence: Low
🔍 Detailed Analysis
The call to classification.response.body.tee() is not wrapped in error handling. If tee() throws (e.g., if the body stream is locked or in an invalid state), this will result in an uncaught exception. This bypasses existing error handling, preventing proper span termination and error capture by Sentry's exception handler.
💡 Suggested Fix
Wrap the classification.response.body.tee() call in a try-catch block to handle potential TypeError exceptions gracefully.
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: packages/cloudflare/src/request.ts#L127-L143
Potential issue: The call to `classification.response.body.tee()` is not wrapped in
error handling. If `tee()` throws (e.g., if the body stream is locked or in an invalid
state), this will result in an uncaught exception. This bypasses existing error
handling, preventing proper span termination and error capture by Sentry's exception
handler.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 2881816
Fixes: https://linear.app/getsentry/issue/JS-1103/spans-are-not-flushed-to-dashboard-when-using-streamtext-with-vercel
The Cloudflare request wrapper was ending the root HTTP span immediately when the handler returned a streaming Response (e.g.
result.toTextStreamResponse()). Since Vercel AI child spans only finish after the stream is consumed by the client, they were filtered out by Sentry'sisFullFinishedSpancheck, resulting in transactions with 0 spans.This PR implements a streaming response detection and handles this from within the http handler:
Created
classifyResponseStreaming()helperUpdated request wrapper
startSpan()tostartSpanManual()for manual span control