mirror of
https://github.com/cloudflare/vinext.git
synced 2026-05-09 08:25:34 +02:00
[PR #916] [MERGED] fix(dev): hoist socket-error backstop to module top-level so lifecycle events can't remove it #947
Labels
No labels
enhancement
enhancement
good first issue
help wanted
nextjs-tracking
nextjs-tracking
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/vinext#947
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/cloudflare/vinext/pull/916
Author: @james-elicx
Created: 4/26/2026
Status: ✅ Merged
Merged: 4/27/2026
Merged by: @james-elicx
Base:
main← Head:claude/dev-socket-debug📝 Commits (10+)
95f00fcdebug(dev): hoist socket-error backstop to module top-level + opt-in trace455a61bfix: address bonk review on dev socket-error backstopffc5684fix(dev): re-hoist socket-error backstop to module load (configureServer too late)05bbaacrefactor(dev): positive-gate socket backstop on argv[2]==='dev'18b4bb0refactor(dev): gate socket backstop on Vite's command==='serve'4683211fix(dev): narrow gate to !isPreview so vite preview skips install501dd95fix: extend socket-error backstop to vinext start (Next.js parity)295099cfix(dev): auto-install socket-error backstop at module load90f7429refactor: call installSocketErrorBackstop directly in index.ts8d044dffix: gate socket backstop on NODE_ENV to keep prerender ECONNRESET fatal📊 Changes
6 files changed (+219 additions, -42 deletions)
View changed files
📝
packages/vinext/src/build/prerender.ts(+11 -4)📝
packages/vinext/src/build/run-prerender.ts(+11 -0)📝
packages/vinext/src/index.ts(+9 -38)📝
packages/vinext/src/server/prod-server.ts(+10 -0)➕
packages/vinext/src/server/socket-error-backstop.ts(+130 -0)➕
tests/socket-error-backstop.test.ts(+48 -0)📄 Description
Summary
Real fix for the residual #905 crashes that #913 didn't catch. Confirmed via the opt-in trace below.
#913 installed the
uncaughtExceptionhandler insideconfigureServerand tore it down onhttpServer'close'. Vite emitscloseon dep re-optimization, full reloads, and other lifecycle events — leaving a window where the listener is absent when a stale stream errors. The exact pattern users were hitting:Reproducer confirmed with the diagnostic flag from this PR:
The marker firing where the crash used to happen confirms the listener is now in place when the error fires.
Changes
Hoist install from
configureServerto module top-level, guarded bySymbol.for("vinext.devSocketErrorBackstop")to prevent double-install (e.g. when vinext is loaded by both a project and a sibling workspace package). No teardown — the listener lives for the process.Add opt-in
VINEXT_DEBUG_SOCKET_ERRORS=1trace that logs when the listener absorbs a peer-disconnect. Default off; useful for confirming the listener fires when users still see crashes in the field.Filter codes (
ECONNRESET/EPIPE/ECONNABORTED) and synchronous re-throw of non-peer-disconnect errors are unchanged from #913.Refs
EventEmitter.prototype.emitpatch was the wrong direction — domain can replace prototype emit on its load, so that approach was fragile)Test plan
vp checkpasses (1 pre-existing benchmarksCannot find module 'vinext'error is unrelated)VINEXT_DEBUG_SOCKET_ERRORS=1 vp devno longer crashes;[vinext] absorbed uncaughtException ECONNRESETprinted where the crash used to be🤖 Generated with Claude Code
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.