diff --git a/src/client.ts b/src/client.ts index 217ba5117..2b413e66a 100644 --- a/src/client.ts +++ b/src/client.ts @@ -559,7 +559,7 @@ export class OpenAI { ); if (options.signal?.aborted) { - throw new Errors.APIUserAbortError(); + throw new Errors.APIUserAbortError({ message: options.signal.reason }); } const controller = new AbortController(); @@ -569,7 +569,7 @@ export class OpenAI { if (response instanceof Error) { const retryMessage = `retrying, ${retriesRemaining} attempts remaining`; if (options.signal?.aborted) { - throw new Errors.APIUserAbortError(); + throw new Errors.APIUserAbortError({ message: options.signal.reason }); } // detect native connection timeout errors // deno throws "TypeError: error sending request for url (https://example/): client error (Connect): tcp connect error: Operation timed out (os error 60): Operation timed out (os error 60)" diff --git a/tests/index.test.ts b/tests/index.test.ts index c8b4b819c..a81171710 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -252,12 +252,33 @@ describe('instantiate client', () => { }); const controller = new AbortController(); - setTimeout(() => controller.abort(), 200); + setTimeout(() => controller.abort('abort test'), 200); - const spy = jest.spyOn(client, 'request'); + const requestSpy = jest.spyOn(client, 'request'); + const fetchWithTimeoutSpy = jest.spyOn(client, 'fetchWithTimeout'); - await expect(client.get('/foo', { signal: controller.signal })).rejects.toThrowError(APIUserAbortError); - expect(spy).toHaveBeenCalledTimes(1); + const abortedRequest = client.get('/foo', { signal: controller.signal }); + await expect(abortedRequest).rejects.toThrow(APIUserAbortError); + await expect(abortedRequest).rejects.toEqual(expect.objectContaining({ message: 'abort test' })); + + expect(requestSpy).toHaveBeenCalledTimes(1); + expect(fetchWithTimeoutSpy).toHaveBeenCalledTimes(1); + }); + + test('should not make a request if the signal is aborted', async () => { + const client = new OpenAI({ baseURL: 'http://localhost:5000/', apiKey: 'My API Key' }); + const requestSpy = jest.spyOn(client, 'request'); + const fetchWithTimeoutSpy = jest.spyOn(client, 'fetchWithTimeout'); + const controller = new AbortController(); + controller.abort(); + const abortedRequest = client.get('/foo', { signal: controller.signal }); + await expect(abortedRequest).rejects.toThrow(APIUserAbortError); + await expect(abortedRequest).rejects.toEqual( + expect.objectContaining({ message: 'AbortError: This operation was aborted' }), + ); + + expect(requestSpy).toHaveBeenCalledTimes(1); + expect(fetchWithTimeoutSpy).toHaveBeenCalledTimes(0); }); test('normalized method', async () => {