Skip to content

Commit

Permalink
types: Make Data type-parameter optional in JsonRpcError (#102)
Browse files Browse the repository at this point in the history
* types: Make Data type-parameter optional in JsonRpcError

This is in order to provide backwards-compatibility with code
implemented towards v5.0.0.

* fix/types: make cause actually optional in DataWithOptionalCause
  • Loading branch information
legobeat authored Aug 28, 2023
1 parent b91c7e8 commit 2b0bcbd
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 36 deletions.
4 changes: 2 additions & 2 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ module.exports = {
global: {
branches: 94.31,
functions: 94.11,
lines: 97.05,
statements: 97.05,
lines: 97.13,
statements: 97.13,
},
},

Expand Down
9 changes: 6 additions & 3 deletions src/classes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
} from '@metamask/utils';
import safeStringify from 'fast-safe-stringify';

import { DataWithOptionalCause, serializeCause } from './utils';
import type { OptionalDataWithOptionalCause } from './utils';
import { serializeCause } from './utils';

export type { SerializedJsonRpcError };

Expand All @@ -15,7 +16,9 @@ export type { SerializedJsonRpcError };
*
* Permits any integer error code.
*/
export class JsonRpcError<T extends DataWithOptionalCause> extends Error {
export class JsonRpcError<
T extends OptionalDataWithOptionalCause,
> extends Error {
public code: number;

public data?: T;
Expand Down Expand Up @@ -81,7 +84,7 @@ export class JsonRpcError<T extends DataWithOptionalCause> extends Error {
* Permits integer error codes in the [ 1000 <= 4999 ] range.
*/
export class EthereumProviderError<
T extends DataWithOptionalCause,
T extends OptionalDataWithOptionalCause,
> extends JsonRpcError<T> {
/**
* Create an Ethereum Provider JSON-RPC error.
Expand Down
69 changes: 39 additions & 30 deletions src/errors.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { JsonRpcError, EthereumProviderError } from './classes';
import { errorCodes } from './error-constants';
import { DataWithOptionalCause, getMessageFromCode } from './utils';
import { OptionalDataWithOptionalCause, getMessageFromCode } from './utils';

type EthereumErrorOptions<T extends DataWithOptionalCause> = {
type EthereumErrorOptions<T extends OptionalDataWithOptionalCause> = {
message?: string;
data?: T;
};

type ServerErrorOptions<T extends DataWithOptionalCause> = {
type ServerErrorOptions<T extends OptionalDataWithOptionalCause> = {
code: number;
} & EthereumErrorOptions<T>;

type CustomErrorArg<T extends DataWithOptionalCause> = ServerErrorOptions<T>;
type CustomErrorArg<T extends OptionalDataWithOptionalCause> =
ServerErrorOptions<T>;

type JsonRpcErrorsArg<T extends DataWithOptionalCause> =
type JsonRpcErrorsArg<T extends OptionalDataWithOptionalCause> =
| EthereumErrorOptions<T>
| string;

Expand All @@ -24,7 +25,7 @@ export const rpcErrors = {
* @param arg - The error message or options bag.
* @returns An instance of the {@link JsonRpcError} class.
*/
parse: <T extends DataWithOptionalCause>(arg?: JsonRpcErrorsArg<T>) =>
parse: <T extends OptionalDataWithOptionalCause>(arg?: JsonRpcErrorsArg<T>) =>
getJsonRpcError(errorCodes.rpc.parse, arg),

/**
Expand All @@ -33,7 +34,7 @@ export const rpcErrors = {
* @param arg - The error message or options bag.
* @returns An instance of the {@link JsonRpcError} class.
*/
invalidRequest: <T extends DataWithOptionalCause>(
invalidRequest: <T extends OptionalDataWithOptionalCause>(
arg?: JsonRpcErrorsArg<T>,
) => getJsonRpcError(errorCodes.rpc.invalidRequest, arg),

Expand All @@ -43,16 +44,17 @@ export const rpcErrors = {
* @param arg - The error message or options bag.
* @returns An instance of the {@link JsonRpcError} class.
*/
invalidParams: <T extends DataWithOptionalCause>(arg?: JsonRpcErrorsArg<T>) =>
getJsonRpcError(errorCodes.rpc.invalidParams, arg),
invalidParams: <T extends OptionalDataWithOptionalCause>(
arg?: JsonRpcErrorsArg<T>,
) => getJsonRpcError(errorCodes.rpc.invalidParams, arg),

/**
* Get a JSON RPC 2.0 Method Not Found (-32601) error.
*
* @param arg - The error message or options bag.
* @returns An instance of the {@link JsonRpcError} class.
*/
methodNotFound: <T extends DataWithOptionalCause>(
methodNotFound: <T extends OptionalDataWithOptionalCause>(
arg?: JsonRpcErrorsArg<T>,
) => getJsonRpcError(errorCodes.rpc.methodNotFound, arg),

Expand All @@ -62,8 +64,9 @@ export const rpcErrors = {
* @param arg - The error message or options bag.
* @returns An instance of the {@link JsonRpcError} class.
*/
internal: <T extends DataWithOptionalCause>(arg?: JsonRpcErrorsArg<T>) =>
getJsonRpcError(errorCodes.rpc.internal, arg),
internal: <T extends OptionalDataWithOptionalCause>(
arg?: JsonRpcErrorsArg<T>,
) => getJsonRpcError(errorCodes.rpc.internal, arg),

/**
* Get a JSON RPC 2.0 Server error.
Expand All @@ -73,7 +76,9 @@ export const rpcErrors = {
* @param opts - The error options bag.
* @returns An instance of the {@link JsonRpcError} class.
*/
server: <T extends DataWithOptionalCause>(opts: ServerErrorOptions<T>) => {
server: <T extends OptionalDataWithOptionalCause>(
opts: ServerErrorOptions<T>,
) => {
if (!opts || typeof opts !== 'object' || Array.isArray(opts)) {
throw new Error(
'Ethereum RPC Server errors must provide single object argument.',
Expand All @@ -94,16 +99,17 @@ export const rpcErrors = {
* @param arg - The error message or options bag.
* @returns An instance of the {@link JsonRpcError} class.
*/
invalidInput: <T extends DataWithOptionalCause>(arg?: JsonRpcErrorsArg<T>) =>
getJsonRpcError(errorCodes.rpc.invalidInput, arg),
invalidInput: <T extends OptionalDataWithOptionalCause>(
arg?: JsonRpcErrorsArg<T>,
) => getJsonRpcError(errorCodes.rpc.invalidInput, arg),

/**
* Get an Ethereum JSON RPC Resource Not Found (-32001) error.
*
* @param arg - The error message or options bag.
* @returns An instance of the {@link JsonRpcError} class.
*/
resourceNotFound: <T extends DataWithOptionalCause>(
resourceNotFound: <T extends OptionalDataWithOptionalCause>(
arg?: JsonRpcErrorsArg<T>,
) => getJsonRpcError(errorCodes.rpc.resourceNotFound, arg),

Expand All @@ -113,7 +119,7 @@ export const rpcErrors = {
* @param arg - The error message or options bag.
* @returns An instance of the {@link JsonRpcError} class.
*/
resourceUnavailable: <T extends DataWithOptionalCause>(
resourceUnavailable: <T extends OptionalDataWithOptionalCause>(
arg?: JsonRpcErrorsArg<T>,
) => getJsonRpcError(errorCodes.rpc.resourceUnavailable, arg),

Expand All @@ -123,7 +129,7 @@ export const rpcErrors = {
* @param arg - The error message or options bag.
* @returns An instance of the {@link JsonRpcError} class.
*/
transactionRejected: <T extends DataWithOptionalCause>(
transactionRejected: <T extends OptionalDataWithOptionalCause>(
arg?: JsonRpcErrorsArg<T>,
) => getJsonRpcError(errorCodes.rpc.transactionRejected, arg),

Expand All @@ -133,7 +139,7 @@ export const rpcErrors = {
* @param arg - The error message or options bag.
* @returns An instance of the {@link JsonRpcError} class.
*/
methodNotSupported: <T extends DataWithOptionalCause>(
methodNotSupported: <T extends OptionalDataWithOptionalCause>(
arg?: JsonRpcErrorsArg<T>,
) => getJsonRpcError(errorCodes.rpc.methodNotSupported, arg),

Expand All @@ -143,8 +149,9 @@ export const rpcErrors = {
* @param arg - The error message or options bag.
* @returns An instance of the {@link JsonRpcError} class.
*/
limitExceeded: <T extends DataWithOptionalCause>(arg?: JsonRpcErrorsArg<T>) =>
getJsonRpcError(errorCodes.rpc.limitExceeded, arg),
limitExceeded: <T extends OptionalDataWithOptionalCause>(
arg?: JsonRpcErrorsArg<T>,
) => getJsonRpcError(errorCodes.rpc.limitExceeded, arg),
};

export const providerErrors = {
Expand All @@ -154,7 +161,7 @@ export const providerErrors = {
* @param arg - The error message or options bag.
* @returns An instance of the {@link EthereumProviderError} class.
*/
userRejectedRequest: <T extends DataWithOptionalCause>(
userRejectedRequest: <T extends OptionalDataWithOptionalCause>(
arg?: JsonRpcErrorsArg<T>,
) => {
return getEthProviderError(errorCodes.provider.userRejectedRequest, arg);
Expand All @@ -166,7 +173,7 @@ export const providerErrors = {
* @param arg - The error message or options bag.
* @returns An instance of the {@link EthereumProviderError} class.
*/
unauthorized: <T extends DataWithOptionalCause>(
unauthorized: <T extends OptionalDataWithOptionalCause>(
arg?: JsonRpcErrorsArg<T>,
) => {
return getEthProviderError(errorCodes.provider.unauthorized, arg);
Expand All @@ -178,7 +185,7 @@ export const providerErrors = {
* @param arg - The error message or options bag.
* @returns An instance of the {@link EthereumProviderError} class.
*/
unsupportedMethod: <T extends DataWithOptionalCause>(
unsupportedMethod: <T extends OptionalDataWithOptionalCause>(
arg?: JsonRpcErrorsArg<T>,
) => {
return getEthProviderError(errorCodes.provider.unsupportedMethod, arg);
Expand All @@ -190,7 +197,7 @@ export const providerErrors = {
* @param arg - The error message or options bag.
* @returns An instance of the {@link EthereumProviderError} class.
*/
disconnected: <T extends DataWithOptionalCause>(
disconnected: <T extends OptionalDataWithOptionalCause>(
arg?: JsonRpcErrorsArg<T>,
) => {
return getEthProviderError(errorCodes.provider.disconnected, arg);
Expand All @@ -202,7 +209,7 @@ export const providerErrors = {
* @param arg - The error message or options bag.
* @returns An instance of the {@link EthereumProviderError} class.
*/
chainDisconnected: <T extends DataWithOptionalCause>(
chainDisconnected: <T extends OptionalDataWithOptionalCause>(
arg?: JsonRpcErrorsArg<T>,
) => {
return getEthProviderError(errorCodes.provider.chainDisconnected, arg);
Expand All @@ -214,7 +221,9 @@ export const providerErrors = {
* @param opts - The error options bag.
* @returns An instance of the {@link EthereumProviderError} class.
*/
custom: <T extends DataWithOptionalCause>(opts: CustomErrorArg<T>) => {
custom: <T extends OptionalDataWithOptionalCause>(
opts: CustomErrorArg<T>,
) => {
if (!opts || typeof opts !== 'object' || Array.isArray(opts)) {
throw new Error(
'Ethereum Provider custom errors must provide single object argument.',
Expand All @@ -237,7 +246,7 @@ export const providerErrors = {
* @param arg - The error message or options bag.
* @returns An instance of the {@link JsonRpcError} class.
*/
function getJsonRpcError<T extends DataWithOptionalCause>(
function getJsonRpcError<T extends OptionalDataWithOptionalCause>(
code: number,
arg?: JsonRpcErrorsArg<T>,
): JsonRpcError<T> {
Expand All @@ -252,7 +261,7 @@ function getJsonRpcError<T extends DataWithOptionalCause>(
* @param arg - The error message or options bag.
* @returns An instance of the {@link EthereumProviderError} class.
*/
function getEthProviderError<T extends DataWithOptionalCause>(
function getEthProviderError<T extends OptionalDataWithOptionalCause>(
code: number,
arg?: JsonRpcErrorsArg<T>,
): EthereumProviderError<T> {
Expand All @@ -270,7 +279,7 @@ function getEthProviderError<T extends DataWithOptionalCause>(
* @param arg - The error message or options bag.
* @returns A tuple containing the error message and optional data.
*/
function parseOpts<T extends DataWithOptionalCause>(
function parseOpts<T extends OptionalDataWithOptionalCause>(
arg?: JsonRpcErrorsArg<T>,
): [message?: string | undefined, data?: T | undefined] {
if (arg) {
Expand Down
10 changes: 9 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,17 @@ export type DataWithOptionalCause =
// 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;
cause?: unknown;
};

/**
* A data object, that must be either:
*
* - A valid DataWithOptionalCause value.
* - undefined.
*/
export type OptionalDataWithOptionalCause = undefined | DataWithOptionalCause;

const FALLBACK_ERROR_CODE = errorCodes.rpc.internal;
const FALLBACK_MESSAGE =
'Unspecified error message. This is a bug, please report it.';
Expand Down

0 comments on commit 2b0bcbd

Please sign in to comment.