Skip to content

Commit

Permalink
Implement throwing native DOMException when possible
Browse files Browse the repository at this point in the history
  • Loading branch information
jopemachine committed Jul 12, 2022
1 parent 0e6f539 commit 83aef43
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 22 deletions.
2 changes: 0 additions & 2 deletions documentation/8-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,4 @@ Always triggers a new retry when thrown.

### `AbortError`

**Code: `ERR_ABORTED`**

When the request is aborted with [AbortController.abort()](https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort).
10 changes: 0 additions & 10 deletions source/core/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,3 @@ export class RetryError extends RequestError {
this.code = 'ERR_RETRYING';
}
}

/**
An error to be thrown when the request is aborted by AbortController.
*/
export class AbortError extends RequestError {
constructor(request: Request, error?: Error) {
super('This operation was aborted.', {...error, code: 'ERR_ABORTED'}, request);
this.name = 'AbortError';
}
}
24 changes: 21 additions & 3 deletions source/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import {
TimeoutError,
UploadError,
CacheError,
AbortError,
} from './errors.js';
import type {PlainResponse} from './response.js';
import type {PromiseCookieJar, NativeRequestOptions, RetryOptions} from './options.js';
Expand Down Expand Up @@ -137,6 +136,25 @@ type UrlType = ConstructorParameters<typeof Options>[0];
type OptionsType = ConstructorParameters<typeof Options>[1];
type DefaultsType = ConstructorParameters<typeof Options>[2];

/**
TODO: Remove AbortError and just throw DOMException when targeting Node 18.
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
const getDOMException = (errorMessage: string) => globalThis.DOMException === undefined
? new Error(errorMessage)
: new DOMException(errorMessage);

/**
TODO: Remove below function and just 'reject(signal.reason)' when targeting Node 18.
*/
const getAbortedReason = (signal: AbortSignal) => {
const reason = (signal as any).reason === undefined
? getDOMException('This operation was aborted.')
: (signal as any).reason;

return reason instanceof Error ? reason : getDOMException(reason);
};

export default class Request extends Duplex implements RequestEvents<Request> {
override ['constructor']: typeof Request;

Expand Down Expand Up @@ -237,11 +255,11 @@ export default class Request extends Duplex implements RequestEvents<Request> {
}

if (this.options.signal?.aborted) {
this.destroy(new AbortError(this, (this.options.signal as any).reason));
this.destroy(getAbortedReason(this.options.signal));
}

this.options.signal?.addEventListener('abort', () => {
this.destroy(new AbortError(this, (this.options.signal as any).reason));
this.destroy(getAbortedReason(this.options.signal!));
});

// Important! If you replace `body` in a handler with another stream, make sure it's readable first.
Expand Down
7 changes: 0 additions & 7 deletions test/abort.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ if (globalThis.AbortController !== undefined) {
});

await t.throwsAsync(gotPromise, {
code: 'ERR_ABORTED',
message: 'This operation was aborted.',
});

Expand Down Expand Up @@ -116,7 +115,6 @@ if (globalThis.AbortController !== undefined) {
});

await t.throwsAsync(gotPromise, {
code: 'ERR_ABORTED',
message: 'This operation was aborted.',
});

Expand All @@ -143,7 +141,6 @@ if (globalThis.AbortController !== undefined) {
});

await t.throwsAsync(gotPromise, {
code: 'ERR_ABORTED',
message: 'This operation was aborted.',
});
await t.notThrowsAsync(promise, 'Request finished instead of aborting.');
Expand All @@ -168,7 +165,6 @@ if (globalThis.AbortController !== undefined) {
});

await t.throwsAsync(gotPromise, {
code: 'ERR_ABORTED',
message: 'This operation was aborted.',
});
await t.notThrowsAsync(promise, 'Request finished instead of aborting.');
Expand All @@ -193,7 +189,6 @@ if (globalThis.AbortController !== undefined) {
controller.abort();

await t.throwsAsync(gotPromise, {
code: 'ERR_ABORTED',
message: 'This operation was aborted.',
});
await t.notThrowsAsync(promise, 'Request finished instead of aborting.');
Expand Down Expand Up @@ -247,7 +242,6 @@ if (globalThis.AbortController !== undefined) {
}, 400);

await t.throwsAsync(promise, {
code: 'ERR_ABORTED',
message: 'This operation was aborted.',
});
});
Expand All @@ -267,7 +261,6 @@ if (globalThis.AbortController !== undefined) {
controller.abort();

await t.throwsAsync(promise, {
code: 'ERR_ABORTED',
message: 'This operation was aborted.',
});
});
Expand Down

0 comments on commit 83aef43

Please sign in to comment.