fix(sse): prevent client-abort (aborted/ECONNRESET) from crashing the server - #11556
Merged
diegosouzapw merged 2 commits intoAug 26, 2026
Merged
diegosouzapw merged 2 commits into
diegosouzapw merged 2 commits into
Conversation
…/prod server A browser closing the TCP socket during navigation/HMR/Back-Forward cache (or nulling the request while the dashboard polls after login) emits Error: aborted / ECONNRESET on the http.IncomingMessage. With no 'error' listener attached, Node re-throws it as an uncaughtException that kills the whole server process — surfacing as a wall of net::ERR_CONNECTION_REFUSED after login (see app.log uncaughtException: aborted). - scripts/dev/httpClientAbortGuard.mjs: reusable guard that attaches req/res 'error' listeners (absorbing client-abort errors) and a process-level uncaughtException/unhandledRejection safety net that swallows benign aborts while preserving crash semantics for real errors. - scripts/dev/run-next.mjs: install the guard in start() and attach per-request stream guards in the request listener. - tests/unit/httpClientAbortGuard.test.mjs: TDD coverage for the exact abortIncoming crash signature + idempotency + crash-semantics preservation.
…, liveWS, embedWS) Extends #fix-dev-server-aborted beyond the Next dev/prod server to the other Node http servers that are equally exposed to a client aborting the TCP socket (navigation/HMR/bfcache) while a response is in flight: - src/lib/apiBridgeServer.ts — the OpenAI-compatible API bridge server. - src/server/ws/liveServer.ts — the live-dashboard WebSocket daemon (20132). - src/lib/services/embedWsProxy.ts — the embedded-service WS proxy (20131). Each now calls attachRequestStreamGuards(req, res) inside its http.createServer request listener, and installProcessCrashGuard() once at start (idempotent process-level safety net). The guard implementation is promoted to a single source of truth at src/shared/utils/httpClientAbortGuard.mjs (importable from both the Node-only dev server and the TypeScript servers; tsconfig allowJs:true). scripts/dev/httpClientAbortGuard.mjs is now a pure re-export so the dev server's existing import path is unchanged. TDD: adds a test asserting the dev re-export is the SAME function objects as the shared module (guards against future drift). Full guard suite stays green (8/8).
25 tasks
This was referenced Aug 26, 2026
This was referenced Aug 29, 2026
diegosouzapw
pushed a commit
that referenced
this pull request
Aug 29, 2026
…2042) Real production incident (2026-08-29): the crash guard #11556 introduced defaulted its logger to `log ?? console` — console is an object, not a function, so a burst of client aborts (ECONNRESET) reaching the process-level guard threw TypeError inside the uncaughtException handler itself and killed the server, twice in three minutes. Fix: default to console.warn.bind(console). Bug-injection round trip confirms the new test fails on the old default and passes on the fix. Existing guard suite stays green: 9/9 (verified together with the new test).
Merged
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
… server (diegosouzapw#11556) Merged via /merge-batch (lote 2026-08-26, v3.8.51). Boarded no worktree combinado junto com outras ~30 PRs; validação única: typecheck/complexity/cognitive-complexity/changelog-integrity verdes, file-size rebaseado onde necessário (crescimento legítimo), lint com os mesmos 228 achados pré-existentes confirmados via sonda contra o tip puro (não introduzidos por este lote), e ~370 testes focados (unit + vitest) passando. Obrigado pela contribuição.
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…egosouzapw#12042) Real production incident (2026-08-29): the crash guard diegosouzapw#11556 introduced defaulted its logger to `log ?? console` — console is an object, not a function, so a burst of client aborts (ECONNRESET) reaching the process-level guard threw TypeError inside the uncaughtException handler itself and killed the server, twice in three minutes. Fix: default to console.warn.bind(console). Bug-injection round trip confirms the new test fails on the old default and passes on the fix. Existing guard suite stays green: 9/9 (verified together with the new test).
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.
fix(sse): prevent client-abort (aborted/ECONNRESET) from crashing the server
Extracted from #11285 (per review feedback — this part is clean, self-contained, and wanted this cycle).
Summary
A client disconnect (
aborted/ECONNRESETon the incoming socket) previously surfaced as an unhandleduncaughtException, crashing the dev and production HTTP server — any browser navigation / HMR / WebSocket disconnect could take the server down.Changes
src/shared/utils/httpClientAbortGuard.mjswithisClientAbortError,shouldSwallowUncaught,attachRequestStreamGuards,installProcessCrashGuard.scripts/dev/run-next.mjs, re-exportscripts/dev/httpClientAbortGuard.mjs).createServercall sites:apiBridgeServer,liveServer(WS),embedWsProxy.tests/unit/httpClientAbortGuard.test.mjs(8/8 passing).Verification
node --test tests/unit/httpClientAbortGuard.test.mjs→ 8/8 passing.uncaughtException: aborted.Base
Targets
release/v3.8.51(this cycle). Rebased from the originalrelease/v3.8.50work.Related: #11285 (full bundle, discussed as RFC in #11288), #11288 (org-layer RFC).