From e06f8d8dc0812d03e4e1aee009dc490d2eb07e44 Mon Sep 17 00:00:00 2001 From: Maarten Zuidhoorn Date: Wed, 19 Apr 2023 11:40:29 +0200 Subject: [PATCH] Allow passing unknown values as cause (#91) * Allow passing unknown values as cause Previously, only the `Error` type as accepted as cause, but since any value can be thrown as error, we have to allow any value to be used. * Update coverage threshold --------- Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> --- jest.config.js | 6 +++--- src/errors.test.ts | 38 ++++++++++++++++++++++++++++++++++++++ src/utils.ts | 9 ++++++--- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/jest.config.js b/jest.config.js index 0ee455d..0acc5bf 100644 --- a/jest.config.js +++ b/jest.config.js @@ -45,10 +45,10 @@ module.exports = { // An object that configures minimum threshold enforcement for coverage results coverageThreshold: { global: { - branches: 94.25, + branches: 94.31, functions: 94.11, - lines: 97.04, - statements: 97.04, + lines: 97.05, + statements: 97.05, }, }, diff --git a/src/errors.test.ts b/src/errors.test.ts index 5a5f69c..9e6a24f 100644 --- a/src/errors.test.ts +++ b/src/errors.test.ts @@ -118,6 +118,25 @@ describe('rpcErrors', () => { }, }); }); + + it('serializes a non-Error-instance cause', () => { + const error = rpcErrors.invalidInput({ + data: { + foo: 'bar', + cause: 'foo', + }, + }); + + const serializedError = error.serialize(); + assert(serializedError.data); + assert(isPlainObject(serializedError.data)); + + expect(serializedError.data.cause).not.toBeInstanceOf(Error); + expect(serializedError.data).toStrictEqual({ + foo: 'bar', + cause: 'foo', + }); + }); }); describe('providerErrors', () => { @@ -169,4 +188,23 @@ describe('providerErrors', () => { }, }); }); + + it('serializes a non-Error-instance cause', () => { + const error = providerErrors.unauthorized({ + data: { + foo: 'bar', + cause: 'foo', + }, + }); + + const serializedError = error.serialize(); + assert(serializedError.data); + assert(isPlainObject(serializedError.data)); + + expect(serializedError.data.cause).not.toBeInstanceOf(Error); + expect(serializedError.data).toStrictEqual({ + foo: 'bar', + cause: 'foo', + }); + }); }); diff --git a/src/utils.ts b/src/utils.ts index 76ed5d5..c6f28c7 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -14,14 +14,17 @@ import { errorCodes, errorValues } from './error-constants'; * A data object, that must be either: * * - A JSON-serializable object. - * - An object with a `cause` property that is an `Error` instance, and any + * - An object with a `cause` property that is an error-like value, and any * other properties that are JSON-serializable. */ export type DataWithOptionalCause = | Json | { - [key: string]: Json | Error; - cause: Error; + // Unfortunately we can't use just `Json` here, because all properties of + // an object with an index signature must be assignable to the index + // signature's type. So we have to use `Json | unknown` instead. + [key: string]: Json | unknown; + cause: unknown; }; const FALLBACK_ERROR_CODE = errorCodes.rpc.internal;