partysocket: failed connections are reported as a clean close with code 1000, so `shouldReconnectOnClose` stops reconnecting

Aperta Adatta ai principianti
#428 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
82/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
node.js, typescript

Direzione di ricerca

Inizia da packages/partysocket/src/ws.ts, soprattutto da _handleError e _disconnect, che l’issue indica come probabile origine dell’evento close sintetico. Confronta l’evento close generato con l’evento close del WebSocket sottostante per le connessioni non riuscite e interrotte. Aggiungi o aggiorna i test per questi casi; il lavoro è completato quando l’evento riporta il codice di errore sottostante e shouldReconnectOnClose consente nuovi tentativi.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

When a connection attempt fails or an open connection drops (server down, network lost), PartySocket dispatches a close event with code: 1000, wasClean: true and reason: "unknown reason", and dispatches it before the error event. The underlying WebSocket reports 1006 / wasClean: false. Because the same synthetic event is passed to the new shouldReconnectOnClose option, a predicate like e => e.code !== 1000 ("reconnect unless the server closed normally") turns reconnection off the first time the server is unreachable.

Reproduction (npm i [email protected], Node 26, nothing listening on port 9):

// repro.mjs
import WebSocket from "partysocket/ws";

// Nothing listens on this port, so every attempt fails.
const ws = new WebSocket("ws://127.0.0.1:9", undefined, {
  minReconnectionDelay: 100,
  // Reconnect unless the server closed normally.
  shouldReconnectOnClose: (e) => e.code !== 1000,
});
ws.addEventListener("close", (e) => console.log("close", e.code, e.wasClean, e.reason));
ws.addEventListener("error", () => console.log("error"));
setTimeout(() => {
  console.log("shouldReconnect", ws.shouldReconnect, "retryCount", ws.retryCount);
  process.exit(0);
}, 2000);

node repro.mjs

Actual:

close 1000 true unknown reason
error
shouldReconnect false retryCount 0

Expected: the close event carries the real code (close 1006 false, which is what new WebSocket("ws://127.0.0.1:9") itself reports), the predicate returns true, and the socket keeps retrying.

The same happens when an established connection is dropped without a close frame (server process killed): the user sees close 1000 true and no reconnect.

Tested with partysocket 1.3.0 and main (cloudflare/partykit f0a2e97d; packages/partysocket/src/ws.ts last changed in 6b977426), on Node 24.22.2, Node 26.13.0 and Bun 1.4.4.

Likely cause: _handleError calls this._disconnect(undefined, ...), so _disconnect(code = 1000, reason) synthesizes new CloseEvent(1000, ...) and removes the listeners, so the real close event from the socket is never seen.

Credit: https://ucsbplse.github.io/

Lingua principale
TypeScript
Stelle
1.3k
Fork
84
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di cloudflare/partykit

Tutte le issue di cloudflare/partykit

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.