Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-reconnect-after-max-retries.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"partysocket": patch
---

Fix `reconnect()` not working after `maxRetries` has been exhausted. The `_connectLock` was not released when the max retries early return was hit in `_connect()`, preventing any subsequent `reconnect()` call from initiating a new connection.
37 changes: 37 additions & 0 deletions packages/partysocket/src/tests/reconnecting.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -937,3 +937,40 @@ testDone("reconnect after closing", (done, fail) => {
}
});
});

testDone(
"reconnect() works after maxRetries has been exhausted",
(done, fail) => {
// Connect to an unreachable URL with maxRetries=0 so retries exhaust quickly.
// This reproduces the bug where _connectLock was not released when
// maxRetries was reached, preventing reconnect() from working.
// (https://github.com/cloudflare/partykit/issues/252)
const ws = new ReconnectingWebSocket(ERROR_URL, undefined, {
maxRetries: 0,
connectionTimeout: 500,
minReconnectionDelay: 10,
maxReconnectionDelay: 50
});

let reconnected = false;
ws.addEventListener("error", () => {
if (reconnected) return;
reconnected = true;

// maxRetries is now exhausted. Switch to the working server and reconnect.
// @ts-expect-error accessing private _url for testing
ws._url = URL;
ws.reconnect();
});

ws.addEventListener("open", () => {
ws.close();
done();
});

setTimeout(() => {
ws.close();
fail(new Error("timed out waiting for reconnect after maxRetries"));
}, 10000);
}
);
1 change: 1 addition & 0 deletions packages/partysocket/src/ws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ export default class ReconnectingWebSocket extends (EventTarget as TypedEventTar

if (this._retryCount >= maxRetries) {
this._debug("max retries reached", this._retryCount, ">=", maxRetries);
this._connectLock = false;
return;
}

Expand Down
Loading