Skip to content

Commit 6d06338

Browse files
authoredDec 18, 2024··
Fix handling of a signal that is already aborted before the request begins (#663)
* fix: throw early if signal is aborted before request is triggered * fix: abort if the original signal also aborted early * fix: linter issues * fix: pass abort reason to early abort * fix: check if server receives request after abort * fix: lint issues
1 parent 1d92c20 commit 6d06338

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed
 

‎source/core/Ky.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,13 @@ export class Ky {
163163
if (supportsAbortController) {
164164
this.abortController = new globalThis.AbortController();
165165
const originalSignal = this._options.signal ?? (this._input as Request).signal;
166+
if (originalSignal?.aborted) {
167+
this.abortController.abort(originalSignal?.reason);
168+
}
169+
166170
originalSignal?.addEventListener('abort', () => {
167171
this.abortController!.abort(originalSignal.reason);
168172
});
169-
170173
this._options.signal = this.abortController.signal;
171174
}
172175

‎test/main.ts

+20
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,26 @@ test('throws DOMException/Error with name AbortError when aborted by user', asyn
713713
t.is(error.name, 'AbortError', `Expected AbortError, got ${error.name}`);
714714
});
715715

716+
test('throws AbortError when signal was aborted before request', async t => {
717+
const server = await createHttpTestServer();
718+
let requestCount = 0;
719+
server.get('/', () => {
720+
requestCount += 1;
721+
});
722+
723+
const abortController = new AbortController();
724+
const {signal} = abortController;
725+
const request = new Request(server.url, {signal});
726+
abortController.abort();
727+
const response = ky(request);
728+
729+
const error = (await t.throwsAsync(response))!;
730+
731+
t.true(['DOMException', 'Error'].includes(error.constructor.name), `Expected DOMException or Error, got ${error.constructor.name}`);
732+
t.is(error.name, 'AbortError', `Expected AbortError, got ${error.name}`);
733+
t.is(requestCount, 0, 'Request count is more than 0, server received request.');
734+
});
735+
716736
test('throws AbortError when aborted via Request', async t => {
717737
const server = await createHttpTestServer();
718738
// eslint-disable-next-line @typescript-eslint/no-empty-function

0 commit comments

Comments
 (0)
Please sign in to comment.