Skip to content

Commit b3385ff

Browse files
fix: make maxReconnectAttempts opt-in, fix test hello-ok response shape
Address ClawSweeper review feedback: - P2: Make reconnect cap opt-in via maxReconnectAttempts option. Undefined = unlimited, preserving node-host unbounded retry behavior. - P3: Fix reset test to send proper type:"res" with payload.type:"hello-ok" instead of type:"connect" so handleMessage actually processes it.
1 parent 71c3132 commit b3385ff

2 files changed

Lines changed: 17 additions & 12 deletions

File tree

src/gateway/client.test.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,7 @@ describe("GatewayClient connect auth payload", () => {
10111011
const onReconnectPaused = vi.fn();
10121012
const client = new GatewayClient({
10131013
url: "ws://127.0.0.1:18789",
1014+
maxReconnectAttempts: 30,
10141015
onReconnectPaused,
10151016
});
10161017

@@ -1056,6 +1057,7 @@ describe("GatewayClient connect auth payload", () => {
10561057
const onReconnectPaused = vi.fn();
10571058
const client = new GatewayClient({
10581059
url: "ws://127.0.0.1:18789",
1060+
maxReconnectAttempts: 10,
10591061
onReconnectPaused,
10601062
});
10611063

@@ -1071,17 +1073,19 @@ describe("GatewayClient connect auth payload", () => {
10711073
// Now succeed — complete the handshake
10721074
const goodWs = getLatestWs();
10731075
goodWs.emitOpen();
1076+
// Find the connect frame the client sent so we can reply with its id
1077+
const lastSent = goodWs.sent.at(-1);
1078+
const connectFrameId = lastSent ? JSON.parse(lastSent).id : "unknown";
10741079
goodWs.emitMessage(
10751080
JSON.stringify({
1076-
type: "connect",
1077-
id: "handshake-1",
1081+
type: "res",
1082+
id: connectFrameId,
10781083
ok: true,
1079-
result: {
1080-
hello: {
1081-
sessionId: "test-session",
1082-
protocol: 1,
1083-
policy: { tickIntervalMs: 30000 },
1084-
},
1084+
payload: {
1085+
type: "hello-ok",
1086+
sessionId: "test-session",
1087+
protocol: 1,
1088+
policy: { tickIntervalMs: 30000 },
10851089
},
10861090
}),
10871091
);

src/gateway/client.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ export type GatewayClientOptions = {
160160
onConnectError?: (err: Error) => void;
161161
onReconnectPaused?: (info: GatewayReconnectPausedInfo) => void;
162162
onClose?: (code: number, reason: string) => void;
163+
/** Maximum reconnect attempts before pausing. Undefined = unlimited (node-host default). */
164+
maxReconnectAttempts?: number;
163165
onGap?: (info: { expected: number; received: number }) => void;
164166
};
165167

@@ -925,18 +927,17 @@ export class GatewayClient {
925927
}, connectChallengeTimeoutMs);
926928
}
927929

928-
private static readonly MAX_RECONNECT_ATTEMPTS = 30;
929-
930930
private scheduleReconnect() {
931931
if (this.closed) {
932932
return;
933933
}
934-
if (this.reconnectAttempts >= GatewayClient.MAX_RECONNECT_ATTEMPTS) {
934+
const maxAttempts = this.opts.maxReconnectAttempts;
935+
if (maxAttempts != null && this.reconnectAttempts >= maxAttempts) {
935936
logDebug(`gateway reconnect giving up after ${this.reconnectAttempts} attempts`);
936937
this.closed = true;
937938
this.opts.onReconnectPaused?.({
938939
code: -1,
939-
reason: `max reconnect attempts reached (${GatewayClient.MAX_RECONNECT_ATTEMPTS})`,
940+
reason: `max reconnect attempts reached (${maxAttempts})`,
940941
detailCode: null,
941942
});
942943
return;

0 commit comments

Comments
 (0)