Skip to content

Commit 0a79c3d

Browse files
committed
fix: correct support AbortSignal:timeout() (refs sindresorhus/got/2371)
1 parent f4f3ba8 commit 0a79c3d

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

source/core/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,12 @@ export default class Request extends Duplex implements RequestEvents<Request> {
264264

265265
if (this.options.signal) {
266266
const abort = () => {
267-
this.destroy(new AbortError(this));
267+
// See https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static#return_value
268+
if (this.options.signal?.reason?.name === 'TimeoutError') {
269+
this.destroy(new TimeoutError(this.options.signal.reason, this.timings!, this));
270+
} else {
271+
this.destroy(new AbortError(this));
272+
}
268273
};
269274

270275
if (this.options.signal.aborted) {

test/abort.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,3 +324,54 @@ test('support setting the signal as a default option', async t => {
324324

325325
t.true(signalHandlersRemoved(), 'Abort signal event handlers not removed');
326326
});
327+
328+
// See https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static
329+
test('support AbortSignal.timeout()', async t => {
330+
const signal = AbortSignal.timeout(1);
331+
332+
const p = got('http://example.com', {signal});
333+
334+
await t.throwsAsync(p, {
335+
code: 23,
336+
message: 'The operation was aborted due to timeout',
337+
});
338+
});
339+
340+
test('support AbortSignal.timeout() without user abort', async t => {
341+
const {controller, signalHandlersRemoved} = createAbortController();
342+
const timeoutSignal = AbortSignal.timeout(1);
343+
const signal = AbortSignal.any([
344+
controller.signal,
345+
timeoutSignal,
346+
]);
347+
const p = got('http://example.com', {signal});
348+
349+
await t.throwsAsync(p, {
350+
code: 23,
351+
message: 'The operation was aborted due to timeout',
352+
});
353+
354+
t.true(signalHandlersRemoved(), 'Abort signal event handlers not removed');
355+
});
356+
357+
test('support AbortSignal.timeout() with user abort', async t => {
358+
const {controller, signalHandlersRemoved} = createAbortController();
359+
const timeoutSignal = AbortSignal.timeout(1000);
360+
const signal = AbortSignal.any([
361+
controller.signal,
362+
timeoutSignal,
363+
]);
364+
365+
setTimeout(() => {
366+
controller.abort();
367+
}, 10);
368+
369+
const p = got('http://example.com', {signal});
370+
371+
await t.throwsAsync(p, {
372+
code: 'ERR_ABORTED',
373+
message: 'This operation was aborted.',
374+
});
375+
376+
t.true(signalHandlersRemoved(), 'Abort signal event handlers not removed');
377+
});

0 commit comments

Comments
 (0)