Skip to content

Commit 9873928

Browse files
sirtimidclaude
andcommitted
fix(ocap-kernel): clean up pending reconnect map entry in outer catch handler
The outer .catch() in #reconnectRelay logged errors but did not remove the relay from #pendingRelayReconnects. If an unexpected throw occurred before the inner try block, the stale entry permanently blocked future reconnection attempts for that relay. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 80d8a8d commit 9873928

2 files changed

Lines changed: 32 additions & 0 deletions

File tree

packages/ocap-kernel/src/remotes/platform/connection-factory.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1622,6 +1622,37 @@ describe('ConnectionFactory', () => {
16221622
expect(pendingTimers).toHaveLength(0);
16231623
});
16241624

1625+
it('cleans up pending reconnect entry when outer catch fires', async () => {
1626+
const mockDial = vi.fn().mockResolvedValue({});
1627+
setupRelayMock(mockDial);
1628+
1629+
factory = await createFactory();
1630+
1631+
// Make logger.log throw when the "attempting relay reconnect" message is
1632+
// logged — this triggers the outer .catch() handler.
1633+
mockLoggerLog.mockImplementation((message: string) => {
1634+
if (
1635+
typeof message === 'string' &&
1636+
message.includes('attempting relay')
1637+
) {
1638+
throw new Error('logger blew up');
1639+
}
1640+
});
1641+
1642+
fireConnectionClose('relay1');
1643+
await runNextTimer();
1644+
1645+
expect(mockLoggerError).toHaveBeenCalledWith(
1646+
'reconnection failed unexpectedly:',
1647+
expect.any(Error),
1648+
);
1649+
1650+
// The pending entry must be removed so future reconnects are not blocked.
1651+
mockLoggerLog.mockReset();
1652+
fireConnectionClose('relay1');
1653+
expect(pendingTimers).toHaveLength(1);
1654+
});
1655+
16251656
it('does not leak timer when stop() runs during in-flight dial', async () => {
16261657
// Dial rejects after stop() has already completed both cleanup passes.
16271658
// The catch block's recursive #reconnectRelay call must not schedule a

packages/ocap-kernel/src/remotes/platform/connection-factory.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ export class ConnectionFactory {
602602
}
603603
})().catch((error) => {
604604
this.#logger.error('reconnection failed unexpectedly:', error);
605+
this.#pendingRelayReconnects.delete(relayPeerId);
605606
});
606607
}, delay);
607608

0 commit comments

Comments
 (0)