fix(router): await server$ stream close so a client disconnect can't crash Bun#8798
Open
aggyomfg wants to merge 2 commits into
Open
fix(router): await server$ stream close so a client disconnect can't crash Bun#8798aggyomfg wants to merge 2 commits into
aggyomfg wants to merge 2 commits into
Conversation
🦋 Changeset detectedLatest commit: 40d2fc2 The changes in this PR will be included in the next version bump. This PR includes changesets to release 5 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
maiieul
reviewed
Jul 7, 2026
| break; | ||
| } | ||
| // Swallow rejection: writable may be errored by a client disconnect. | ||
| await stream.write(encoder.encode(`${message}\n`)).catch(() => {}); |
Member
There was a problem hiding this comment.
Could we log the error message in dev mode at least?
| } | ||
| } | ||
|
|
||
| // Streams an async-iterator server function result to the response writable. A mid-stream |
@qwik.dev/core
@qwik.dev/router
eslint-plugin-qwik
create-qwik
@qwik.dev/optimizer
@qwik.dev/devtools
commit: |
Contributor
built with Refined Cloudflare Pages Action⚡ Cloudflare Pages Deployment
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is it?
Description
A streaming
server$(anasync function*consumed as a stream) crashes theentire Bun process when the client disconnects mid-stream (SPA navigation
away, tab close, refresh, network drop).
When the client goes away, the response writable is errored, so
write/closereject. The async-iterator branch of
runServerFunctioncalledstream.close()without awaiting or catching it, so the rejection went unhandled. On Bun the
default
unhandledRejectionbehavior is to abort the process (Node only logs awarning, which is why this stayed hidden there). After the crash every following
request fails with
ECONNREFUSED— the server is gone.The fix extracts the streaming branch into
streamServerFunctionResultandawaits + swallows both the per-itemwriteand the finalclose, so adisconnected writable tears down quietly instead of leaking a rejection.
Reproduction: a streaming
server$on the Bun adapter — open the stream,read one chunk, then abort the request while it is still producing; the process
exits.
Related: #5929 (fixed the
TextEncoderStreampolyfill, not this close),#4381 (Node
ERR_STREAM_DESTROYEDon the same class of teardown),oven-sh/bun#18228 (Bun's stance: the framework must catch the close).
Test drives
streamServerFunctionResultwith a writable whoseclose()rejects (thepost-disconnect state) and asserts no unhandled rejection escapes. It is red
without the fix (leaks
Cannot close a writable stream that is closed or errored) and green with it. The process-abort half is Bun-specific and can't bereproduced under Node, but the leaked-rejection root cause is covered here.
Checklist
pnpm change