diff --git a/src/actions/public/watchContractEvent.test.ts b/src/actions/public/watchContractEvent.test.ts index 53e35d3897..3fae64d69a 100644 --- a/src/actions/public/watchContractEvent.test.ts +++ b/src/actions/public/watchContractEvent.test.ts @@ -1567,4 +1567,34 @@ describe('subscribe', () => { unwatch() }) }) + + test( + 'https://github.com/wevm/viem/issues/2563', + async () => { + let error: Error | undefined + const unwatch = watchContractEvent(webSocketClient, { + ...usdcContractConfig, + onError: (error_) => { + error = error_ + }, + onLogs: () => {}, + }) + + await wait(100) + const { socket } = await webSocketClient.transport.getRpcClient() + socket.close() + await wait(100) + + expect(error).toMatchInlineSnapshot(` + [SocketClosedError: The socket has been closed. + + URL: http://localhost + + Version: viem@x.y.z] + `) + + unwatch() + }, + { timeout: 10_000 }, + ) }) diff --git a/src/clients/transports/webSocket.test.ts b/src/clients/transports/webSocket.test.ts index 705ae3f85e..49c850cbe9 100644 --- a/src/clients/transports/webSocket.test.ts +++ b/src/clients/transports/webSocket.test.ts @@ -185,6 +185,39 @@ test('subscribe', async () => { expect(blocks.length).toBe(1) }) +test('throws on socket closure', async () => { + const transport = webSocket(anvilMainnet.rpcUrl.ws, { + key: 'jsonRpc', + name: 'JSON RPC', + })({}) + if (!transport.value) return + + let error: Error | undefined + const { subscriptionId } = await transport.value.subscribe({ + params: ['newHeads'], + onData: () => {}, + onError: (error_) => { + error = error_ + }, + }) + + // Make sure we are subscribed. + expect(subscriptionId).toBeDefined() + + await wait(100) + const { socket } = await transport.value.getRpcClient() + socket.close() + await wait(100) + + expect(error).toMatchInlineSnapshot(` + [SocketClosedError: The socket has been closed. + + URL: http://localhost + + Version: viem@x.y.z] + `) +}) + test('throws on bogus subscription', async () => { const transport = webSocket(anvilMainnet.rpcUrl.ws, { key: 'jsonRpc', diff --git a/src/clients/transports/webSocket.ts b/src/clients/transports/webSocket.ts index ab585887b3..a156ef28fc 100644 --- a/src/clients/transports/webSocket.ts +++ b/src/clients/transports/webSocket.ts @@ -144,6 +144,11 @@ export function webSocket( method: 'eth_subscribe', params, }, + onError(error) { + reject(error) + onError?.(error) + return + }, onResponse(response) { if (response.error) { reject(response.error)