Replies: 1 comment
|
Confirmed against v0.1.1-rc.2 source — your diagnosis is exact, and I traced the asymmetry that makes this a one-line bug rather than a design decision. Source facts (packages/host/webserver/src/index.ts)
README contract (packages/host/webserver/README.md line 9) states verbatim: "An upgrade-handler exception or upgraded-socket transport error is logged as a warning and destroys its socket" — the observed behavior (process exit) violates it. Fix (2 lines, minimal)
Regression test: your repro is already a test — after close, assert the upgraded socket still has at least one error listener, then emit an error on it: it must not throw and must not reach an uncaught-exception handler. Add a second case for the double-error path (error after destroy) to assert no warn spam. Family: teardown-timing cleanup overreach — the same shape as #4055 (client-hmr SSE upgrade channel) and the earlier quiesce work: a "stop acting on the thing" cleanup that accidentally removes the safety net. Worth a sweep for other Note for maintainers: commit |
Uh oh!
There was an error while loading. Please reload this page.
Summary
@deepseek-ai/dsh-host-webserver@0.1.1-rc.2removes its upgraded socketerrorlistener in the socket'sclosecallback. A transport error delivered after that callback, such as a lateECONNRESETduring a browser reload or tunnel disconnect, then has no listener and is thrown as an unhandled EventEmitter error. This can terminate the entiredsh webprocess.I found this while testing an unofficial community plugin, but the reproduction below uses only the official published
dsh-host-webserverpackage and@deepseek-ai/cordis.This appears to conflict with the package README contract: an upgraded-socket transport error should be logged and its socket destroyed, and should never exit the process.
Environment
@deepseek-ai/dsh-host-webserver:0.1.1-rc.2(current npm release)0.1.0-rc.8; the relevant lifecycle is unchanged@deepseek-ai/cordis:4.0.1v25.4.0Relevant lifecycle
The upgrade handler installs
onError, then removes it onclose:Node may still deliver a queued transport error after the close callback has run.
Minimal reproduction
Install the two published packages in an empty directory, then run:
Observed:
The same probe leaves one listener and does not throw when a connection-lifetime compatibility listener is added before the upgrade.
Expected behavior
A late transport error on a closed upgraded socket must not become an uncaught exception or terminate the Harness process. The server should remain available for subsequent HTTP and WebSocket connections.
Suggested acceptance criteria
ECONNRESETdoes not throw.packages/host/webserver/tests/webserver.spec.ts.A possible implementation is to retain an
errorlistener for the socket's full object lifetime, or replace the logging handler with a no-op listener after close. The exact ownership choice is best made by the package maintainers.Related failure class: #3251 reports another process-fatal transport gap, but it concerns SDK stdout
EPIPE; this report is specifically the WebServer upgraded-socket close race.All reactions