Skip to content

Commit

Permalink
Add EIP1193ProviderRpcError and use it when provider _onDisconnect
Browse files Browse the repository at this point in the history
  • Loading branch information
Muhammad-Altabba committed Jun 26, 2023
1 parent 3f49e18 commit f2aa5fc
Show file tree
Hide file tree
Showing 9 changed files with 270 additions and 23 deletions.
4 changes: 3 additions & 1 deletion packages/web3-errors/src/error_codes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ export const ERR_INVALID_SIGNATURE = 802;

export const GENESIS_BLOCK_NUMBER = '0x0';

// RPC error codes (EIP-1193)
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1193.md#provider-errors
export const JSONRPC_ERR_REJECTED_REQUEST = 4001;
export const JSONRPC_ERR_UNAUTHORIZED = 4100;
Expand Down Expand Up @@ -159,7 +160,8 @@ export const ERR_VALIDATION = 1100;
export const ERR_CORE_HARDFORK_MISMATCH = 1101;
export const ERR_CORE_CHAIN_MISMATCH = 1102;

// rpc error codes EIP-1474
// RPC error codes (EIP-1474)
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1474.md
export const ERR_RPC_INVALID_JSON = -32700;
export const ERR_RPC_INVALID_REQUEST = -32600;
export const ERR_RPC_INVALID_METHOD = -32601;
Expand Down
214 changes: 214 additions & 0 deletions packages/web3-errors/src/errors/rpc_error_messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
/*
This file is part of web3.js.
web3.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
web3.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/

import {

Check warning on line 18 in packages/web3-errors/src/errors/rpc_error_messages.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_error_messages.ts#L18

Added line #L18 was not covered by tests
ERR_RPC_INTERNAL_ERROR,
ERR_RPC_INVALID_INPUT,
ERR_RPC_INVALID_JSON,
ERR_RPC_INVALID_METHOD,
ERR_RPC_INVALID_PARAMS,
ERR_RPC_INVALID_REQUEST,
ERR_RPC_LIMIT_EXCEEDED,
ERR_RPC_MISSING_RESOURCE,
ERR_RPC_NOT_SUPPORTED,
ERR_RPC_TRANSACTION_REJECTED,
ERR_RPC_UNAVAILABLE_RESOURCE,
ERR_RPC_UNSUPPORTED_METHOD,
JSONRPC_ERR_CHAIN_DISCONNECTED,
JSONRPC_ERR_DISCONNECTED,
JSONRPC_ERR_REJECTED_REQUEST,
JSONRPC_ERR_UNAUTHORIZED,
JSONRPC_ERR_UNSUPPORTED_METHOD,
} from '../error_codes';

/* eslint-disable @typescript-eslint/naming-convention */
export const RpcErrorMessages: {

Check warning on line 39 in packages/web3-errors/src/errors/rpc_error_messages.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_error_messages.ts#L39

Added line #L39 was not covered by tests
[key: number | string]: { name?: string; message: string; description?: string };
} = {
// EIP-1474 & JSON RPC 2.0
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1474.md
[ERR_RPC_INVALID_JSON]: {
message: 'Parse error',
description: 'Invalid JSON',
},
[ERR_RPC_INVALID_REQUEST]: {
message: 'Invalid request',
description: 'JSON is not a valid request object ',
},
[ERR_RPC_INVALID_METHOD]: {
message: 'Method not found',
description: 'Method does not exist ',
},
[ERR_RPC_INVALID_PARAMS]: {
message: 'Invalid params',
description: 'Invalid method parameters',
},
[ERR_RPC_INTERNAL_ERROR]: {
message: 'Internal error',
description: 'Internal JSON-RPC error',
},

[ERR_RPC_INVALID_INPUT]: {
message: 'Invalid input',
description: 'Missing or invalid parameters',
},
[ERR_RPC_MISSING_RESOURCE]: {
message: 'Resource not found',
description: 'Requested resource not found',
},
[ERR_RPC_UNAVAILABLE_RESOURCE]: {
message: 'Resource unavailable',
description: 'Requested resource not available',
},
[ERR_RPC_TRANSACTION_REJECTED]: {
message: 'Transaction rejected',
description: 'Transaction creation failed',
},
[ERR_RPC_UNSUPPORTED_METHOD]: {
message: 'Method not supported',
description: 'Method is not implemented',
},
[ERR_RPC_LIMIT_EXCEEDED]: {
message: 'Limit exceeded',
description: 'Request exceeds defined limit',
},
[ERR_RPC_NOT_SUPPORTED]: {
message: 'JSON-RPC version not supported',
description: 'Version of JSON-RPC protocol is not supported',
},

// EIP-1193
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1193.md#provider-errors
[JSONRPC_ERR_REJECTED_REQUEST]: {
name: 'User Rejected Request',
message: 'The user rejected the request.',
},
[JSONRPC_ERR_UNAUTHORIZED]: {
name: 'Unauthorized',
message: 'The requested method and/or account has not been authorized by the user.',
},
[JSONRPC_ERR_UNSUPPORTED_METHOD]: {
name: 'Unsupported Method',
message: 'The Provider does not support the requested method.',
},
[JSONRPC_ERR_DISCONNECTED]: {
name: 'Disconnected',
message: 'The Provider is disconnected from all chains.',
},
[JSONRPC_ERR_CHAIN_DISCONNECTED]: {
name: 'Chain Disconnected',
message: 'The Provider is not connected to the requested chain.',
},

// EIP-1193 - CloseEvent
// https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code
'0-999': {
name: '',
message: 'Not used.',
},
1000: {
name: 'Normal Closure',
message: 'The connection successfully completed the purpose for which it was created.',
},
1001: {
name: 'Going Away',
message:
'The endpoint is going away, either because of a server failure or because the browser is navigating away from the page that opened the connection.',
},
1002: {
name: 'Protocol error',
message: 'The endpoint is terminating the connection due to a protocol error.',
},
1003: {
name: 'Unsupported Data',
message:
'The connection is being terminated because the endpoint received data of a type it cannot accept. (For example, a text-only endpoint received binary data.)',
},
1004: {
name: 'Reserved',
message: 'Reserved. A meaning might be defined in the future.',
},
1005: {
name: 'No Status Rcvd',
message:
'Reserved. Indicates that no status code was provided even though one was expected.',
},
1006: {
name: 'Abnormal Closure',
message:
'Reserved. Indicates that a connection was closed abnormally (that is, with no close frame being sent) when a status code is expected.',
},
1007: {
name: 'Invalid frame payload data',
message:
'The endpoint is terminating the connection because a message was received that contained inconsistent data (e.g., non-UTF-8 data within a text message).',
},
1008: {
name: 'Policy Violation',
message:
'The endpoint is terminating the connection because it received a message that violates its policy. This is a generic status code, used when codes 1003 and 1009 are not suitable.',
},
1009: {
name: 'Message Too Big',
message:
'The endpoint is terminating the connection because a data frame was received that is too large.',
},
1010: {
name: 'Mandatory Ext.',
message:
"The client is terminating the connection because it expected the server to negotiate one or more extension, but the server didn't.",
},
1011: {
name: 'Internal Error',
message:
'The server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request.',
},
1012: {
name: 'Service Restart',
message: 'The server is terminating the connection because it is restarting.',
},
1013: {
name: 'Try Again Later',
message:
'The server is terminating the connection due to a temporary condition, e.g. it is overloaded and is casting off some of its clients.',
},
1014: {
name: 'Bad Gateway',
message:
'The server was acting as a gateway or proxy and received an invalid response from the upstream server. This is similar to 502 HTTP Status Code.',
},
1015: {
name: 'TLS handshake',
message:
"Reserved. Indicates that the connection was closed due to a failure to perform a TLS handshake (e.g., the server certificate can't be verified).",
},
'1016-2999': {
name: '',
message:
'For definition by future revisions of the WebSocket Protocol specification, and for definition by extension specifications.',
},
'3000-3999': {
name: '',
message:
'For use by libraries, frameworks, and applications. These status codes are registered directly with IANA. The interpretation of these codes is undefined by the WebSocket protocol.',
},
'4000-4999': {
name: '',
message:
"For private use, and thus can't be registered. Such codes can be used by prior agreements between WebSocket applications. The interpretation of these codes is undefined by the WebSocket protocol.",
},
};
57 changes: 44 additions & 13 deletions packages/web3-errors/src/errors/rpc_errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,17 @@ import {
ERR_RPC_UNAVAILABLE_RESOURCE,
ERR_RPC_UNSUPPORTED_METHOD,
} from '../error_codes.js';
import { RpcErrorMessages } from './rpc_error_messages.js';

Check warning on line 36 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L36

Added line #L36 was not covered by tests

const genericRpcMessage = 'An Rpc error has occured with a code of *code*';

Check warning on line 38 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L38

Added line #L38 was not covered by tests

export class RpcError extends BaseWeb3Error {
public code: number;
public id: JsonRpcId;
public jsonrpc: string;
public jsonRpcError: JsonRpcError;
public constructor(rpcError: JsonRpcResponseWithError, message?: string) {
super(message ?? `An Rpc error has occured with a code of ${rpcError.error.code}`);
super(message ?? genericRpcMessage.replace('*code*', rpcError.error.code.toString()));

Check warning on line 46 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L46

Added line #L46 was not covered by tests
this.code = rpcError.error.code;
this.id = rpcError.id;
this.jsonrpc = rpcError.jsonrpc;
Expand All @@ -52,87 +55,115 @@ export class RpcError extends BaseWeb3Error {
}
}

export class EIP1193ProviderRpcError extends BaseWeb3Error {

Check warning on line 58 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L58

Added line #L58 was not covered by tests
public code: number;
public data?: unknown;

public constructor(code: number, data?: unknown) {
if (!code) {

Check warning on line 63 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L62-L63

Added lines #L62 - L63 were not covered by tests
// this case should ideally not happen
super();
} else if (RpcErrorMessages[code]?.message) {
super(RpcErrorMessages[code].message);
} else {

Check warning on line 68 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L65-L68

Added lines #L65 - L68 were not covered by tests
// Retrieve the status code object for the given code from the table, by searching through the appropriate range
const statusCodeRange = Object.keys(RpcErrorMessages).find(

Check warning on line 70 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L70

Added line #L70 was not covered by tests
statusCode =>
typeof statusCode === 'string' &&
code >= parseInt(statusCode.split('-')[0], 10) &&
code <= parseInt(statusCode.split('-')[1], 10),

Check warning on line 74 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L72-L74

Added lines #L72 - L74 were not covered by tests
);
super(
RpcErrorMessages[statusCodeRange ?? '']?.message ??
genericRpcMessage.replace('*code*', code?.toString() ?? '""'),

Check warning on line 78 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L76-L78

Added lines #L76 - L78 were not covered by tests
);
}
this.code = code;
this.data = data;

Check warning on line 82 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L81-L82

Added lines #L81 - L82 were not covered by tests
}
}

export class ParseError extends RpcError {
public code = ERR_RPC_INVALID_JSON;
public constructor(rpcError: JsonRpcResponseWithError) {
super(rpcError, 'Parse error');
super(rpcError, RpcErrorMessages[ERR_RPC_INVALID_JSON].message);

Check warning on line 89 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L89

Added line #L89 was not covered by tests
}
}

export class InvalidRequestError extends RpcError {
public code = ERR_RPC_INVALID_REQUEST;
public constructor(rpcError: JsonRpcResponseWithError) {
super(rpcError, 'Invalid request');
super(rpcError, RpcErrorMessages[ERR_RPC_INVALID_REQUEST].message);

Check warning on line 96 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L96

Added line #L96 was not covered by tests
}
}

export class MethodNotFoundError extends RpcError {
public code = ERR_RPC_INVALID_METHOD;
public constructor(rpcError: JsonRpcResponseWithError) {
super(rpcError, 'Method not found');
super(rpcError, RpcErrorMessages[ERR_RPC_INVALID_METHOD].message);

Check warning on line 103 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L103

Added line #L103 was not covered by tests
}
}

export class InvalidParamsError extends RpcError {
public code = ERR_RPC_INVALID_PARAMS;
public constructor(rpcError: JsonRpcResponseWithError) {
super(rpcError, 'Invalid request');
super(rpcError, RpcErrorMessages[ERR_RPC_INVALID_PARAMS].message);

Check warning on line 110 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L110

Added line #L110 was not covered by tests
}
}

export class InternalError extends RpcError {
public code = ERR_RPC_INTERNAL_ERROR;
public constructor(rpcError: JsonRpcResponseWithError) {
super(rpcError, 'Internal error');
super(rpcError, RpcErrorMessages[ERR_RPC_INTERNAL_ERROR].message);

Check warning on line 117 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L117

Added line #L117 was not covered by tests
}
}

export class InvalidInputError extends RpcError {
public code = ERR_RPC_INVALID_INPUT;
public constructor(rpcError: JsonRpcResponseWithError) {
super(rpcError, 'Invalid input');
super(rpcError, RpcErrorMessages[ERR_RPC_INVALID_INPUT].message);

Check warning on line 124 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L124

Added line #L124 was not covered by tests
}
}

export class MethodNotSupported extends RpcError {
public code = ERR_RPC_UNSUPPORTED_METHOD;
public constructor(rpcError: JsonRpcResponseWithError) {
super(rpcError, 'Method not supported');
super(rpcError, RpcErrorMessages[ERR_RPC_UNSUPPORTED_METHOD].message);

Check warning on line 131 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L131

Added line #L131 was not covered by tests
}
}

export class ResourceUnavailableError extends RpcError {
public code = ERR_RPC_UNAVAILABLE_RESOURCE;
public constructor(rpcError: JsonRpcResponseWithError) {
super(rpcError, 'Resource unavailable');
super(rpcError, RpcErrorMessages[ERR_RPC_UNAVAILABLE_RESOURCE].message);

Check warning on line 138 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L138

Added line #L138 was not covered by tests
}
}

export class ResourcesNotFoundError extends RpcError {
public code = ERR_RPC_MISSING_RESOURCE;
public constructor(rpcError: JsonRpcResponseWithError) {
super(rpcError, 'Resource not found');
super(rpcError, RpcErrorMessages[ERR_RPC_MISSING_RESOURCE].message);

Check warning on line 145 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L145

Added line #L145 was not covered by tests
}
}

export class VersionNotSupportedError extends RpcError {
public code = ERR_RPC_NOT_SUPPORTED;
public constructor(rpcError: JsonRpcResponseWithError) {
super(rpcError, 'JSON-RPC version not supported');
super(rpcError, RpcErrorMessages[ERR_RPC_NOT_SUPPORTED].message);

Check warning on line 152 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L152

Added line #L152 was not covered by tests
}
}

export class TransactionRejectedError extends RpcError {
public code = ERR_RPC_TRANSACTION_REJECTED;
public constructor(rpcError: JsonRpcResponseWithError) {
super(rpcError, 'Transaction rejected');
super(rpcError, RpcErrorMessages[ERR_RPC_TRANSACTION_REJECTED].message);

Check warning on line 159 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L159

Added line #L159 was not covered by tests
}
}

export class LimitExceededError extends RpcError {
public code = ERR_RPC_LIMIT_EXCEEDED;
public constructor(rpcError: JsonRpcResponseWithError) {
super(rpcError, 'Limit exceeded');
super(rpcError, RpcErrorMessages[ERR_RPC_LIMIT_EXCEEDED].message);

Check warning on line 166 in packages/web3-errors/src/errors/rpc_errors.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/errors/rpc_errors.ts#L166

Added line #L166 was not covered by tests
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/web3-errors/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ export * from './errors/utils_errors.js';
export * from './errors/response_errors.js';
export * from './errors/core_errors.js';
export * from './errors/rpc_errors.js';
export * from './errors/rpc_error_messages.js';

Check warning on line 32 in packages/web3-errors/src/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-errors/src/index.ts#L32

Added line #L32 was not covered by tests
1 change: 1 addition & 0 deletions packages/web3-eth-iban/src/iban.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ export class Iban {
* const iban = new web3.eth.Iban('XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS');
* iban.toString();
* > 'XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS'
* ```
*/
public toString(): string {
return this._iban;
Expand Down
Loading

0 comments on commit f2aa5fc

Please sign in to comment.