Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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)"
Expand Down
29 changes: 25 additions & 4 deletions tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down