From 6de619312b6fb19d9ea3377a158a0d588bcff250 Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Thu, 11 May 2023 17:39:29 -0500 Subject: [PATCH 01/10] refactor(TimeoutError): removing downlevel workaround --- src/internal/operators/timeout.ts | 47 ++++++++++--------------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/src/internal/operators/timeout.ts b/src/internal/operators/timeout.ts index b18a14d9d8..11094ebd31 100644 --- a/src/internal/operators/timeout.ts +++ b/src/internal/operators/timeout.ts @@ -4,7 +4,6 @@ import { isValidDate } from '../util/isDate'; import { Subscription } from '../Subscription'; import { Observable } from '../Observable'; import { from } from '../observable/from'; -import { createErrorClass } from '../util/createErrorClass'; import { createOperatorSubscriber } from './OperatorSubscriber'; import { executeSchedule } from '../util/executeSchedule'; @@ -50,28 +49,6 @@ export interface TimeoutInfo { readonly lastValue: T | null; } -/** - * An error emitted when a timeout occurs. - */ -export interface TimeoutError extends Error { - /** - * The information provided to the error by the timeout - * operation that created the error. Will be `null` if - * used directly in non-RxJS code with an empty constructor. - * (Note that using this constructor directly is not recommended, - * you should create your own errors) - */ - info: TimeoutInfo | null; -} - -export interface TimeoutErrorCtor { - /** - * @deprecated Internal implementation detail. Do not construct error instances. - * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269 - */ - new (info?: TimeoutInfo): TimeoutError; -} - /** * An error thrown by the {@link timeout} operator. * @@ -82,15 +59,21 @@ export interface TimeoutErrorCtor { * * @see {@link timeout} */ -export const TimeoutError: TimeoutErrorCtor = createErrorClass( - (_super) => - function TimeoutErrorImpl(this: any, info: TimeoutInfo | null = null) { - _super(this); - this.message = 'Timeout has occurred'; - this.name = 'TimeoutError'; - this.info = info; - } -); +export class TimeoutError extends Error { + /** + * @param info The information provided to the error by the timeout + * operation that created the error. Will be `null` if + * used directly in non-RxJS code with an empty constructor. + * (Note that using this constructor directly is not recommended, + * you should create your own errors) + * @deprecated Internal implementation detail. Do not construct error instances. + * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269 + */ + constructor(public info: TimeoutInfo | null = null) { + super('Timeout has occurred'); + this.name = 'TimeoutError'; + } +} /** * If `with` is provided, this will return an observable that will switch to a different observable if the source From f85eb15927496cad3d6c5adc37731d6710fa12c2 Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Thu, 11 May 2023 17:41:53 -0500 Subject: [PATCH 02/10] refactor(UnsubscriptionError): remove downlevel workaround --- src/internal/util/UnsubscriptionError.ts | 37 +++++++++--------------- 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/src/internal/util/UnsubscriptionError.ts b/src/internal/util/UnsubscriptionError.ts index cd7d09f429..f0e3456d08 100644 --- a/src/internal/util/UnsubscriptionError.ts +++ b/src/internal/util/UnsubscriptionError.ts @@ -1,30 +1,19 @@ -import { createErrorClass } from './createErrorClass'; - -export interface UnsubscriptionError extends Error { - readonly errors: any[]; -} - -export interface UnsubscriptionErrorCtor { - /** - * @deprecated Internal implementation detail. Do not construct error instances. - * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269 - */ - new (errors: any[]): UnsubscriptionError; -} - /** * An error thrown when one or more errors have occurred during the * `unsubscribe` of a {@link Subscription}. */ -export const UnsubscriptionError: UnsubscriptionErrorCtor = createErrorClass( - (_super) => - function UnsubscriptionErrorImpl(this: any, errors: (Error | string)[]) { - _super(this); - this.message = errors +export class UnsubscriptionError extends Error { + /** + * @deprecated Internal implementation detail. Do not construct error instances. + * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269 + */ + constructor(public errors: any[]) { + super( + errors ? `${errors.length} errors occurred during unsubscription: ${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\n ')}` - : ''; - this.name = 'UnsubscriptionError'; - this.errors = errors; - } -); + : '' + ); + this.name = 'UnsubscriptionError'; + } +} From 0c9a45f5c6670ef6194e6fc3178b49841e934e01 Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Thu, 11 May 2023 17:43:56 -0500 Subject: [PATCH 03/10] refactor(SequenceError): remove downlevel workaround --- src/internal/util/SequenceError.ts | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/internal/util/SequenceError.ts b/src/internal/util/SequenceError.ts index 06483d0701..2bfe0228dc 100644 --- a/src/internal/util/SequenceError.ts +++ b/src/internal/util/SequenceError.ts @@ -1,26 +1,16 @@ -import { createErrorClass } from './createErrorClass'; - -export interface SequenceError extends Error {} - -export interface SequenceErrorCtor { - /** - * @deprecated Internal implementation detail. Do not construct error instances. - * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269 - */ - new (message: string): SequenceError; -} - /** * An error thrown when something is wrong with the sequence of * values arriving on the observable. * * @see {@link operators/single} */ -export const SequenceError: SequenceErrorCtor = createErrorClass( - (_super) => - function SequenceErrorImpl(this: any, message: string) { - _super(this); - this.name = 'SequenceError'; - this.message = message; - } -); +export class SequenceError extends Error { + /** + * @deprecated Internal implementation detail. Do not construct error instances. + * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269 + */ + constructor(message: string) { + super(message); + this.name = 'SequenceError'; + } +} From cad325f8facee49aff63f0fb5b452b030cecab84 Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Thu, 11 May 2023 17:45:00 -0500 Subject: [PATCH 04/10] refactor(NotFoundError): remove downlevel workaround --- src/internal/util/NotFoundError.ts | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/internal/util/NotFoundError.ts b/src/internal/util/NotFoundError.ts index ecd213fd3a..dfcec39584 100644 --- a/src/internal/util/NotFoundError.ts +++ b/src/internal/util/NotFoundError.ts @@ -1,26 +1,16 @@ -import { createErrorClass } from './createErrorClass'; - -export interface NotFoundError extends Error {} - -export interface NotFoundErrorCtor { - /** - * @deprecated Internal implementation detail. Do not construct error instances. - * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269 - */ - new (message: string): NotFoundError; -} - /** * An error thrown when a value or values are missing from an * observable sequence. * * @see {@link operators/single} */ -export const NotFoundError: NotFoundErrorCtor = createErrorClass( - (_super) => - function NotFoundErrorImpl(this: any, message: string) { - _super(this); - this.name = 'NotFoundError'; - this.message = message; - } -); +export class NotFoundError extends Error { + /** + * @deprecated Internal implementation detail. Do not construct error instances. + * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269 + */ + constructor(message: string) { + super(message); + this.name = 'NotFoundError'; + } +} From 9a136a18239580266150dcc321f4f2ad681a7cb3 Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Thu, 11 May 2023 17:49:25 -0500 Subject: [PATCH 05/10] refactor(EmptyError): remove downleveling workaround --- src/internal/util/EmptyError.ts | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/internal/util/EmptyError.ts b/src/internal/util/EmptyError.ts index eb2c5e3159..d903bbe627 100644 --- a/src/internal/util/EmptyError.ts +++ b/src/internal/util/EmptyError.ts @@ -1,15 +1,3 @@ -import { createErrorClass } from './createErrorClass'; - -export interface EmptyError extends Error {} - -export interface EmptyErrorCtor { - /** - * @deprecated Internal implementation detail. Do not construct error instances. - * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269 - */ - new (): EmptyError; -} - /** * An error thrown when an Observable or a sequence was queried but has no * elements. @@ -20,11 +8,13 @@ export interface EmptyErrorCtor { * @see {@link firstValueFrom} * @see {@link lastValueFrom} */ -export const EmptyError: EmptyErrorCtor = createErrorClass( - (_super) => - function EmptyErrorImpl(this: any) { - _super(this); - this.name = 'EmptyError'; - this.message = 'no elements in sequence'; - } -); +export class EmptyError extends Error { + /** + * @deprecated Internal implementation detail. Do not construct error instances. + * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269 + */ + constructor() { + super('no elements in sequence'); + this.name = 'EmptyError'; + } +} From 687e412cbf6327dc269660818cf00e53cf4ef968 Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Thu, 11 May 2023 17:49:52 -0500 Subject: [PATCH 06/10] refactor(ArgumentOutOfRangeError): remove downleveling workaround --- src/internal/util/ArgumentOutOfRangeError.ts | 30 +++++++------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/internal/util/ArgumentOutOfRangeError.ts b/src/internal/util/ArgumentOutOfRangeError.ts index 9a89d7694b..502311240a 100644 --- a/src/internal/util/ArgumentOutOfRangeError.ts +++ b/src/internal/util/ArgumentOutOfRangeError.ts @@ -1,15 +1,3 @@ -import { createErrorClass } from './createErrorClass'; - -export interface ArgumentOutOfRangeError extends Error {} - -export interface ArgumentOutOfRangeErrorCtor { - /** - * @deprecated Internal implementation detail. Do not construct error instances. - * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269 - */ - new (): ArgumentOutOfRangeError; -} - /** * An error thrown when an element was queried at a certain index of an * Observable, but no such index or position exists in that sequence. @@ -18,11 +6,13 @@ export interface ArgumentOutOfRangeErrorCtor { * @see {@link take} * @see {@link takeLast} */ -export const ArgumentOutOfRangeError: ArgumentOutOfRangeErrorCtor = createErrorClass( - (_super) => - function ArgumentOutOfRangeErrorImpl(this: any) { - _super(this); - this.name = 'ArgumentOutOfRangeError'; - this.message = 'argument out of range'; - } -); +export class ArgumentOutOfRangeError extends Error { + /** + * @deprecated Internal implementation detail. Do not construct error instances. + * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269 + */ + constructor() { + super('argument out of range'); + this.name = 'ArgumentOutOfRangeError'; + } +} From 15c74f60f0059fcf5d41a9c85e8edfa86c0cdaec Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Thu, 11 May 2023 17:50:09 -0500 Subject: [PATCH 07/10] refactor(AjaxError): remove downleveling workaround --- src/internal/ajax/errors.ts | 51 ++++++++++++++----------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/src/internal/ajax/errors.ts b/src/internal/ajax/errors.ts index 119a578817..595fb17b25 100644 --- a/src/internal/ajax/errors.ts +++ b/src/internal/ajax/errors.ts @@ -1,68 +1,55 @@ import { AjaxRequest } from './types'; -import { createErrorClass } from '../util/createErrorClass'; /** - * A normalized AJAX error. + * Thrown when an error occurs during an AJAX request. + * This is only exported because it is useful for checking to see if an error + * is an `instanceof AjaxError`. DO NOT create new instances of `AjaxError` with + * the constructor. * * @see {@link ajax} */ -export interface AjaxError extends Error { +class AjaxError extends Error { /** * The XHR instance associated with the error. */ - xhr: XMLHttpRequest; + readonly xhr: XMLHttpRequest; /** * The AjaxRequest associated with the error. */ - request: AjaxRequest; + readonly request: AjaxRequest; /** * The HTTP status code, if the request has completed. If not, * it is set to `0`. */ - status: number; + readonly status: number; /** * The responseType (e.g. 'json', 'arraybuffer', or 'xml'). */ - responseType: XMLHttpRequestResponseType; + readonly responseType: XMLHttpRequestResponseType; /** * The response data. */ - response: any; -} + readonly response: any; -export interface AjaxErrorCtor { /** * @deprecated Internal implementation detail. Do not construct error instances. * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269 */ - new (message: string, xhr: XMLHttpRequest, request: AjaxRequest): AjaxError; + constructor(message: string, xhr: XMLHttpRequest, request: AjaxRequest) { + super(message); + this.name = 'AjaxError'; + this.xhr = xhr; + this.request = request; + this.status = xhr.status; + this.responseType = xhr.responseType; + this.response = xhr.response; + } } -/** - * Thrown when an error occurs during an AJAX request. - * This is only exported because it is useful for checking to see if an error - * is an `instanceof AjaxError`. DO NOT create new instances of `AjaxError` with - * the constructor. - * - * @see {@link ajax} - */ -export const AjaxError: AjaxErrorCtor = createErrorClass( - (_super) => - function AjaxErrorImpl(this: any, message: string, xhr: XMLHttpRequest, request: AjaxRequest) { - this.message = message; - this.name = 'AjaxError'; - this.xhr = xhr; - this.request = request; - this.status = xhr.status; - this.responseType = xhr.responseType; - this.response = xhr.response; - } -); - export interface AjaxTimeoutError extends AjaxError {} export interface AjaxTimeoutErrorCtor { From 0d7b42b73ed7aceb866c933d6eb832f389d0cd1d Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Thu, 11 May 2023 17:50:28 -0500 Subject: [PATCH 08/10] refactor: remove unused `createErrorClass` workaround --- spec/util/createErrorClass-spec.ts | 27 --------------------------- src/internal/util/createErrorClass.ts | 20 -------------------- 2 files changed, 47 deletions(-) delete mode 100644 spec/util/createErrorClass-spec.ts delete mode 100644 src/internal/util/createErrorClass.ts diff --git a/spec/util/createErrorClass-spec.ts b/spec/util/createErrorClass-spec.ts deleted file mode 100644 index 9086c81341..0000000000 --- a/spec/util/createErrorClass-spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** @prettier */ -import { createErrorClass } from 'rxjs/internal/util/createErrorClass'; -import { expect } from 'chai'; - -describe('createErrorClass', () => { - it('should create a class that subclasses error and has the right properties', () => { - const MySpecialError: any = createErrorClass( - (_super) => - function MySpecialError(this: any, arg1: number, arg2: string) { - _super(this); - this.message = 'Super special error!'; - this.arg1 = arg1; - this.arg2 = arg2; - } - ); - - expect(MySpecialError).to.be.a('function'); - const err = new MySpecialError(123, 'Test'); - expect(err).to.be.an.instanceOf(Error); - expect(err).to.be.an.instanceOf(MySpecialError); - expect(err.constructor).to.equal(MySpecialError); - expect(err.stack).to.be.a('string'); - expect(err.message).to.equal('Super special error!'); - expect(err.arg1).to.equal(123); - expect(err.arg2).to.equal('Test'); - }); -}); diff --git a/src/internal/util/createErrorClass.ts b/src/internal/util/createErrorClass.ts deleted file mode 100644 index e354fd389e..0000000000 --- a/src/internal/util/createErrorClass.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Used to create Error subclasses until the community moves away from ES5. - * - * This is because compiling from TypeScript down to ES5 has issues with subclassing Errors - * as well as other built-in types: https://github.com/Microsoft/TypeScript/issues/12123 - * - * @param createImpl A factory function to create the actual constructor implementation. The returned - * function should be a named function that calls `_super` internally. - */ -export function createErrorClass(createImpl: (_super: any) => any): T { - const _super = (instance: any) => { - Error.call(instance); - instance.stack = new Error().stack; - }; - - const ctorFunc = createImpl(_super); - ctorFunc.prototype = Object.create(Error.prototype); - ctorFunc.prototype.constructor = ctorFunc; - return ctorFunc; -} From 5b0c064c852b75e1c5b6168616f15a0ce154943b Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Thu, 11 May 2023 17:52:39 -0500 Subject: [PATCH 09/10] refactor(AjaxTimeoutError): Implement as non downlevel workaround --- src/internal/ajax/errors.ts | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/internal/ajax/errors.ts b/src/internal/ajax/errors.ts index 595fb17b25..df4a8483b1 100644 --- a/src/internal/ajax/errors.ts +++ b/src/internal/ajax/errors.ts @@ -50,16 +50,6 @@ class AjaxError extends Error { } } -export interface AjaxTimeoutError extends AjaxError {} - -export interface AjaxTimeoutErrorCtor { - /** - * @deprecated Internal implementation detail. Do not construct error instances. - * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269 - */ - new (xhr: XMLHttpRequest, request: AjaxRequest): AjaxTimeoutError; -} - /** * Thrown when an AJAX request times out. Not to be confused with {@link TimeoutError}. * @@ -69,12 +59,13 @@ export interface AjaxTimeoutErrorCtor { * * @see {@link ajax} */ -export const AjaxTimeoutError: AjaxTimeoutErrorCtor = (() => { - function AjaxTimeoutErrorImpl(this: any, xhr: XMLHttpRequest, request: AjaxRequest) { - AjaxError.call(this, 'ajax timeout', xhr, request); +export class AjaxTimeoutError extends AjaxError { + /** + * @deprecated Internal implementation detail. Do not construct error instances. + * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269 + */ + constructor(xhr: XMLHttpRequest, request: AjaxRequest) { + super('ajax timeout', xhr, request); this.name = 'AjaxTimeoutError'; - return this; } - AjaxTimeoutErrorImpl.prototype = Object.create(AjaxError.prototype); - return AjaxTimeoutErrorImpl; -})() as any; +} From 07b648d5a51701f6c02395b486520399ce46df03 Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Thu, 11 May 2023 17:53:42 -0500 Subject: [PATCH 10/10] refactor(AjaxError): remember to export the class, silly! --- src/internal/ajax/errors.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal/ajax/errors.ts b/src/internal/ajax/errors.ts index df4a8483b1..cd87edfe8c 100644 --- a/src/internal/ajax/errors.ts +++ b/src/internal/ajax/errors.ts @@ -8,7 +8,7 @@ import { AjaxRequest } from './types'; * * @see {@link ajax} */ -class AjaxError extends Error { +export class AjaxError extends Error { /** * The XHR instance associated with the error. */