diff --git a/package-lock.json b/package-lock.json index c15797d2..cb193ff6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,8 +31,7 @@ "@web3auth/base-provider": "^7.3.1", "bn.js": "^5.2.1", "bowser": "^2.11.0", - "elliptic": "^6.5.4", - "ts-custom-error": "^3.3.1" + "elliptic": "^6.5.4" }, "devDependencies": { "@babel/register": "^7.23.7", diff --git a/package.json b/package.json index f67a69aa..37ab4958 100644 --- a/package.json +++ b/package.json @@ -57,8 +57,7 @@ "@web3auth/base-provider": "^7.3.1", "bn.js": "^5.2.1", "bowser": "^2.11.0", - "elliptic": "^6.5.4", - "ts-custom-error": "^3.3.1" + "elliptic": "^6.5.4" }, "devDependencies": { "@babel/register": "^7.23.7", diff --git a/src/helper/errors.ts b/src/helper/errors.ts index bdb58ddd..6ac174f3 100644 --- a/src/helper/errors.ts +++ b/src/helper/errors.ts @@ -1,4 +1,80 @@ -import { CustomError } from "ts-custom-error"; +/** + * Fix the prototype chain of the error + * + * Use Object.setPrototypeOf + * Support ES6 environments + * + * Fallback setting __proto__ + * Support IE11+, see https://docs.microsoft.com/en-us/scripting/javascript/reference/javascript-version-information + */ +function fixProto(target: Error, prototype: object) { + const { setPrototypeOf } = Object; + if (setPrototypeOf) { + setPrototypeOf(target, prototype); + } else { + // eslint-disable-next-line no-proto, @typescript-eslint/no-explicit-any + (target as any).__proto__ = prototype; + } +} + +/** + * Capture and fix the error stack when available + * + * Use Error.captureStackTrace + * Support v8 environments + */ +function fixStack(target: Error, fn = target.constructor) { + const { captureStackTrace } = Error; + if (captureStackTrace) { + captureStackTrace(target, fn); + } +} + +// copy from https://github.com/microsoft/TypeScript/blob/main/lib/lib.es2022.error.d.ts +// avoid typescript isue https://github.com/adriengibrat/ts-custom-error/issues/81 +interface ErrorOptions { + cause?: unknown; +} + +/** + * Allows to easily extend a base class to create custom applicative errors. + * + * example: + * ``` + * class HttpError extends CustomError { + * public constructor( + * public code: number, + * message?: string, + * cause?: Error, + * ) { + * super(message, { cause }) + * } + * } + * + * new HttpError(404, 'Not found') + * ``` + */ +export class CustomError extends Error { + name: string; + + constructor(message?: string, options?: ErrorOptions) { + super(message, options); + // set error name as constructor name, make it not enumerable to keep native Error behavior + // see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new.target#new.target_in_constructors + // see https://github.com/adriengibrat/ts-custom-error/issues/30 + Object.defineProperty(this, "name", { + value: new.target.name, + enumerable: false, + configurable: true, + }); + // fix the extended error prototype chain + // because typescript __extends implementation can't + // see https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work + fixProto(this, new.target.prototype); + // try to remove contructor from stack trace + fixStack(this); + } +} interface ICoreKitError extends CustomError { name: string;