From b8941ce28d3a35dbfbc0973a8daab7cc21a12f85 Mon Sep 17 00:00:00 2001 From: mukunda katta Date: Mon, 20 Apr 2026 23:08:05 -0700 Subject: [PATCH] fix(client): clean up caller abort listener --- src/client.ts | 1 + tests/index.test.ts | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/client.ts b/src/client.ts index f55a6b986..c95ac47fb 100644 --- a/src/client.ts +++ b/src/client.ts @@ -892,6 +892,7 @@ export class OpenAI { return await this.fetch.call(undefined, url, fetchOptions); } finally { clearTimeout(timeout); + if (signal) signal.removeEventListener('abort', abort); } } diff --git a/tests/index.test.ts b/tests/index.test.ts index f15b518e9..b82329e93 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -276,6 +276,28 @@ describe('instantiate client', () => { expect(spy).toHaveBeenCalledTimes(1); }); + test('removes the caller abort listener after a successful request', async () => { + const client = new OpenAI({ + baseURL: 'http://localhost:5000/', + apiKey: 'My API Key', + fetch: async () => + new Response(JSON.stringify({ ok: true }), { + headers: { 'Content-Type': 'application/json' }, + }), + }); + + const controller = new AbortController(); + const addSpy = jest.spyOn(controller.signal, 'addEventListener'); + const removeSpy = jest.spyOn(controller.signal, 'removeEventListener'); + + await client.get('/foo', { signal: controller.signal }); + + expect(addSpy).toHaveBeenCalledWith('abort', expect.any(Function), { once: true }); + const listener = addSpy.mock.calls[0]?.[1]; + expect(listener).toBeDefined(); + expect(removeSpy).toHaveBeenCalledWith('abort', listener); + }); + test('normalized method', async () => { let capturedRequest: RequestInit | undefined; const testFetch = async (url: string | URL | Request, init: RequestInit = {}): Promise => {