diff --git a/packages/web3-errors/CHANGELOG.md b/packages/web3-errors/CHANGELOG.md
index bb8a5ac7bff..7e4a438007e 100644
--- a/packages/web3-errors/CHANGELOG.md
+++ b/packages/web3-errors/CHANGELOG.md
@@ -131,3 +131,11 @@ Documentation:
- Dependencies updated
## [Unreleased]
+
+### Added
+
+- `RpcErrorMessages` that contains mapping for standard RPC Errors and their messages. (#6230)
+
+### Fixed
+
+- Fixed: "'disconnect' in Eip1193 provider must emit ProviderRpcError #6003".(#6230)
diff --git a/packages/web3-errors/src/error_codes.ts b/packages/web3-errors/src/error_codes.ts
index c62644c44bb..20e07b39a1a 100644
--- a/packages/web3-errors/src/error_codes.ts
+++ b/packages/web3-errors/src/error_codes.ts
@@ -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;
@@ -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;
diff --git a/packages/web3-errors/src/errors/rpc_error_messages.ts b/packages/web3-errors/src/errors/rpc_error_messages.ts
new file mode 100644
index 00000000000..49e13d7f61f
--- /dev/null
+++ b/packages/web3-errors/src/errors/rpc_error_messages.ts
@@ -0,0 +1,221 @@
+/*
+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 .
+*/
+
+import {
+ 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';
+
+/**
+ * A template string for a generic Rpc Error. The `*code*` will be replaced with the code number.
+ * Note: consider in next version that a spelling mistake could be corrected for `occured` and the value could be:
+ * `An Rpc error has occurred with a code of *code*`
+ */
+export const genericRpcErrorMessageTemplate = 'An Rpc error has occured with a code of *code*';
+
+/* eslint-disable @typescript-eslint/naming-convention */
+export const RpcErrorMessages: {
+ [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.",
+ },
+};
diff --git a/packages/web3-errors/src/errors/rpc_errors.ts b/packages/web3-errors/src/errors/rpc_errors.ts
index 718fb99be6b..d7f7e899e59 100644
--- a/packages/web3-errors/src/errors/rpc_errors.ts
+++ b/packages/web3-errors/src/errors/rpc_errors.ts
@@ -33,6 +33,7 @@ import {
ERR_RPC_UNAVAILABLE_RESOURCE,
ERR_RPC_UNSUPPORTED_METHOD,
} from '../error_codes.js';
+import { RpcErrorMessages, genericRpcErrorMessageTemplate } from './rpc_error_messages.js';
export class RpcError extends BaseWeb3Error {
public code: number;
@@ -40,7 +41,10 @@ export class RpcError extends BaseWeb3Error {
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 ??
+ genericRpcErrorMessageTemplate.replace('*code*', rpcError.error.code.toString()),
+ );
this.code = rpcError.error.code;
this.id = rpcError.id;
this.jsonrpc = rpcError.jsonrpc;
@@ -52,87 +56,115 @@ export class RpcError extends BaseWeb3Error {
}
}
+export class EIP1193ProviderRpcError extends BaseWeb3Error {
+ public code: number;
+ public data?: unknown;
+
+ public constructor(code: number, data?: unknown) {
+ if (!code) {
+ // this case should ideally not happen
+ super();
+ } else if (RpcErrorMessages[code]?.message) {
+ super(RpcErrorMessages[code].message);
+ } else {
+ // Retrieve the status code object for the given code from the table, by searching through the appropriate range
+ const statusCodeRange = Object.keys(RpcErrorMessages).find(
+ statusCode =>
+ typeof statusCode === 'string' &&
+ code >= parseInt(statusCode.split('-')[0], 10) &&
+ code <= parseInt(statusCode.split('-')[1], 10),
+ );
+ super(
+ RpcErrorMessages[statusCodeRange ?? '']?.message ??
+ genericRpcErrorMessageTemplate.replace('*code*', code?.toString() ?? '""'),
+ );
+ }
+ this.code = code;
+ this.data = data;
+ }
+}
+
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
diff --git a/packages/web3-errors/src/index.ts b/packages/web3-errors/src/index.ts
index 6a19d428f33..5916321f8a6 100644
--- a/packages/web3-errors/src/index.ts
+++ b/packages/web3-errors/src/index.ts
@@ -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';
diff --git a/packages/web3-errors/test/unit/__snapshots__/rpc-errors.test.ts.snap b/packages/web3-errors/test/unit/__snapshots__/rpc-errors.test.ts.snap
new file mode 100644
index 00000000000..93330d6576f
--- /dev/null
+++ b/packages/web3-errors/test/unit/__snapshots__/rpc-errors.test.ts.snap
@@ -0,0 +1,294 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`rpc errors EIP1193ProviderRpcError test constructor with a known code (1000) 1`] = `
+Object {
+ "code": 1000,
+ "innerError": undefined,
+ "message": "The connection successfully completed the purpose for which it was created.",
+ "name": "EIP1193ProviderRpcError",
+}
+`;
+
+exports[`rpc errors EIP1193ProviderRpcError test constructor with no code 1`] = `
+Object {
+ "code": undefined,
+ "innerError": undefined,
+ "message": "",
+ "name": "EIP1193ProviderRpcError",
+}
+`;
+
+exports[`rpc errors EIP1193ProviderRpcError test constructor with un registered code 1`] = `
+Object {
+ "code": 99999,
+ "innerError": undefined,
+ "message": "An Rpc error has occured with a code of 99999",
+ "name": "EIP1193ProviderRpcError",
+}
+`;
+
+exports[`rpc errors InternalError test constructor 1`] = `
+Object {
+ "code": -32603,
+ "error": Object {
+ "code": 123,
+ "data": Object {
+ "a": "10",
+ "b": "20",
+ },
+ "message": "error message",
+ },
+ "id": 1,
+ "innerError": undefined,
+ "jsonRpc": "2.0",
+ "message": "Internal error",
+ "name": "InternalError",
+}
+`;
+
+exports[`rpc errors InvalidInputError test constructor 1`] = `
+Object {
+ "code": -32000,
+ "error": Object {
+ "code": 123,
+ "data": Object {
+ "a": "10",
+ "b": "20",
+ },
+ "message": "error message",
+ },
+ "id": 1,
+ "innerError": undefined,
+ "jsonRpc": "2.0",
+ "message": "Invalid input",
+ "name": "InvalidInputError",
+}
+`;
+
+exports[`rpc errors InvalidParamsError test constructor 1`] = `
+Object {
+ "code": -32602,
+ "error": Object {
+ "code": 123,
+ "data": Object {
+ "a": "10",
+ "b": "20",
+ },
+ "message": "error message",
+ },
+ "id": 1,
+ "innerError": undefined,
+ "jsonRpc": "2.0",
+ "message": "Invalid params",
+ "name": "InvalidParamsError",
+}
+`;
+
+exports[`rpc errors InvalidRequestError test constructor 1`] = `
+Object {
+ "code": -32600,
+ "error": Object {
+ "code": 123,
+ "data": Object {
+ "a": "10",
+ "b": "20",
+ },
+ "message": "error message",
+ },
+ "id": 1,
+ "innerError": undefined,
+ "jsonRpc": "2.0",
+ "message": "Invalid request",
+ "name": "InvalidRequestError",
+}
+`;
+
+exports[`rpc errors LimitExceededError test constructor 1`] = `
+Object {
+ "code": -32005,
+ "error": Object {
+ "code": 123,
+ "data": Object {
+ "a": "10",
+ "b": "20",
+ },
+ "message": "error message",
+ },
+ "id": 1,
+ "innerError": undefined,
+ "jsonRpc": "2.0",
+ "message": "Limit exceeded",
+ "name": "LimitExceededError",
+}
+`;
+
+exports[`rpc errors MethodNotFoundError test constructor 1`] = `
+Object {
+ "code": -32601,
+ "error": Object {
+ "code": 123,
+ "data": Object {
+ "a": "10",
+ "b": "20",
+ },
+ "message": "error message",
+ },
+ "id": 1,
+ "innerError": undefined,
+ "jsonRpc": "2.0",
+ "message": "Method not found",
+ "name": "MethodNotFoundError",
+}
+`;
+
+exports[`rpc errors MethodNotSupported test constructor 1`] = `
+Object {
+ "code": -32004,
+ "error": Object {
+ "code": 123,
+ "data": Object {
+ "a": "10",
+ "b": "20",
+ },
+ "message": "error message",
+ },
+ "id": 1,
+ "innerError": undefined,
+ "jsonRpc": "2.0",
+ "message": "Method not supported",
+ "name": "MethodNotSupported",
+}
+`;
+
+exports[`rpc errors ParseError test constructor 1`] = `
+Object {
+ "code": -32700,
+ "error": Object {
+ "code": 123,
+ "data": Object {
+ "a": "10",
+ "b": "20",
+ },
+ "message": "error message",
+ },
+ "id": 1,
+ "innerError": undefined,
+ "jsonRpc": "2.0",
+ "message": "Parse error",
+ "name": "ParseError",
+}
+`;
+
+exports[`rpc errors ResourceUnavailableError test constructor 1`] = `
+Object {
+ "code": -32002,
+ "error": Object {
+ "code": 123,
+ "data": Object {
+ "a": "10",
+ "b": "20",
+ },
+ "message": "error message",
+ },
+ "id": 1,
+ "innerError": undefined,
+ "jsonRpc": "2.0",
+ "message": "Resource unavailable",
+ "name": "ResourceUnavailableError",
+}
+`;
+
+exports[`rpc errors ResourcesNotFoundError test constructor 1`] = `
+Object {
+ "code": -32001,
+ "error": Object {
+ "code": 123,
+ "data": Object {
+ "a": "10",
+ "b": "20",
+ },
+ "message": "error message",
+ },
+ "id": 1,
+ "innerError": undefined,
+ "jsonRpc": "2.0",
+ "message": "Resource not found",
+ "name": "ResourcesNotFoundError",
+}
+`;
+
+exports[`rpc errors TransactionRejectedError test constructor 1`] = `
+Object {
+ "code": -32003,
+ "error": Object {
+ "code": 123,
+ "data": Object {
+ "a": "10",
+ "b": "20",
+ },
+ "message": "error message",
+ },
+ "id": 1,
+ "innerError": undefined,
+ "jsonRpc": "2.0",
+ "message": "Transaction rejected",
+ "name": "TransactionRejectedError",
+}
+`;
+
+exports[`rpc errors VersionNotSupportedError test constructor 1`] = `
+Object {
+ "code": -32006,
+ "error": Object {
+ "code": 123,
+ "data": Object {
+ "a": "10",
+ "b": "20",
+ },
+ "message": "error message",
+ },
+ "id": 1,
+ "innerError": undefined,
+ "jsonRpc": "2.0",
+ "message": "JSON-RPC version not supported",
+ "name": "VersionNotSupportedError",
+}
+`;
+
+exports[`rpc errors rpcErrors.RpcError test constructor 1`] = `
+Object {
+ "code": 123,
+ "error": Object {
+ "code": 123,
+ "data": Object {
+ "a": "10",
+ "b": "20",
+ },
+ "message": "error message",
+ },
+ "id": 1,
+ "innerError": undefined,
+ "jsonRpc": "2.0",
+ "message": "An Rpc error has occured with a code of 123",
+ "name": "RpcError",
+}
+`;
+
+exports[`rpc errors rpcErrors.RpcError test constructor with custom message 1`] = `
+Object {
+ "code": 123,
+ "error": Object {
+ "code": 123,
+ "data": Object {
+ "a": "10",
+ "b": "20",
+ },
+ "message": "error message",
+ },
+ "id": 1,
+ "innerError": undefined,
+ "jsonRpc": "2.0",
+ "message": "some message",
+ "name": "RpcError",
+}
+`;
diff --git a/packages/web3-errors/test/unit/rpc-errors.test.ts b/packages/web3-errors/test/unit/rpc-errors.test.ts
new file mode 100644
index 00000000000..584b9397216
--- /dev/null
+++ b/packages/web3-errors/test/unit/rpc-errors.test.ts
@@ -0,0 +1,149 @@
+/*
+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 .
+*/
+
+import { JsonRpcIdentifier } from 'web3-types';
+
+import * as rpcErrors from '../../src/errors/rpc_errors';
+import { RpcErrorMessages } from '../../src/errors/rpc_error_messages';
+
+const rpcReturnedError = {
+ id: 1,
+ jsonrpc: '2.0' as JsonRpcIdentifier,
+ error: { code: 123, message: 'error message', data: { a: '10', b: '20' } },
+};
+
+describe('rpc errors', () => {
+ describe('rpcErrorsMap', () => {
+ it('child RpcError classes should be also mapped inside `rpcErrorsMap`', () => {
+ expect(
+ Object.values(rpcErrors).filter(
+ err =>
+ (err as any).prototype?.constructor?.prototype instanceof
+ rpcErrors.RpcError,
+ ),
+ ).toHaveLength(rpcErrors.rpcErrorsMap.size);
+ });
+ });
+
+ describe('rpcErrors.RpcError', () => {
+ it('test constructor', () => {
+ expect(new rpcErrors.RpcError(rpcReturnedError).toJSON()).toMatchSnapshot();
+ });
+ it('test constructor with custom message', () => {
+ expect(
+ new rpcErrors.RpcError(rpcReturnedError, `some message`).toJSON(),
+ ).toMatchSnapshot();
+ });
+ });
+
+ describe('EIP1193ProviderRpcError', () => {
+ it('test constructor with no code', () => {
+ expect(
+ new rpcErrors.EIP1193ProviderRpcError(undefined as unknown as number).toJSON(),
+ ).toMatchSnapshot();
+ });
+ it('test constructor with a known code (1000)', () => {
+ const code = 1000;
+ const error = new rpcErrors.EIP1193ProviderRpcError(code);
+ expect(error.toJSON()).toMatchSnapshot();
+ expect(error.message).toEqual(RpcErrorMessages[code].message);
+ });
+ it('test constructor with un registered code', () => {
+ expect(new rpcErrors.EIP1193ProviderRpcError(99999).toJSON()).toMatchSnapshot();
+ });
+ });
+
+ describe('ParseError', () => {
+ it('test constructor', () => {
+ expect(new rpcErrors.ParseError(rpcReturnedError).toJSON()).toMatchSnapshot();
+ });
+ });
+
+ describe('InvalidRequestError', () => {
+ it('test constructor', () => {
+ expect(new rpcErrors.InvalidRequestError(rpcReturnedError).toJSON()).toMatchSnapshot();
+ });
+ });
+
+ describe('MethodNotFoundError', () => {
+ it('test constructor', () => {
+ expect(new rpcErrors.MethodNotFoundError(rpcReturnedError).toJSON()).toMatchSnapshot();
+ });
+ });
+
+ describe('InvalidParamsError', () => {
+ it('test constructor', () => {
+ expect(new rpcErrors.InvalidParamsError(rpcReturnedError).toJSON()).toMatchSnapshot();
+ });
+ });
+
+ describe('InternalError', () => {
+ it('test constructor', () => {
+ expect(new rpcErrors.InternalError(rpcReturnedError).toJSON()).toMatchSnapshot();
+ });
+ });
+
+ describe('InvalidInputError', () => {
+ it('test constructor', () => {
+ expect(new rpcErrors.InvalidInputError(rpcReturnedError).toJSON()).toMatchSnapshot();
+ });
+ });
+
+ describe('MethodNotSupported', () => {
+ it('test constructor', () => {
+ expect(new rpcErrors.MethodNotSupported(rpcReturnedError).toJSON()).toMatchSnapshot();
+ });
+ });
+
+ describe('ResourceUnavailableError', () => {
+ it('test constructor', () => {
+ expect(
+ new rpcErrors.ResourceUnavailableError(rpcReturnedError).toJSON(),
+ ).toMatchSnapshot();
+ });
+ });
+
+ describe('ResourcesNotFoundError', () => {
+ it('test constructor', () => {
+ expect(
+ new rpcErrors.ResourcesNotFoundError(rpcReturnedError).toJSON(),
+ ).toMatchSnapshot();
+ });
+ });
+
+ describe('VersionNotSupportedError', () => {
+ it('test constructor', () => {
+ expect(
+ new rpcErrors.VersionNotSupportedError(rpcReturnedError).toJSON(),
+ ).toMatchSnapshot();
+ });
+ });
+
+ describe('TransactionRejectedError', () => {
+ it('test constructor', () => {
+ expect(
+ new rpcErrors.TransactionRejectedError(rpcReturnedError).toJSON(),
+ ).toMatchSnapshot();
+ });
+ });
+
+ describe('LimitExceededError', () => {
+ it('test constructor', () => {
+ expect(new rpcErrors.LimitExceededError(rpcReturnedError).toJSON()).toMatchSnapshot();
+ });
+ });
+});
diff --git a/packages/web3-eth-iban/src/iban.ts b/packages/web3-eth-iban/src/iban.ts
index 598b4b62dd6..db7e024e3cf 100644
--- a/packages/web3-eth-iban/src/iban.ts
+++ b/packages/web3-eth-iban/src/iban.ts
@@ -389,6 +389,7 @@ export class Iban {
* const iban = new web3.eth.Iban('XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS');
* iban.toString();
* > 'XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS'
+ * ```
*/
public toString(): string {
return this._iban;
diff --git a/packages/web3-providers-ipc/src/index.ts b/packages/web3-providers-ipc/src/index.ts
index 99546513fc8..641d36ea083 100644
--- a/packages/web3-providers-ipc/src/index.ts
+++ b/packages/web3-providers-ipc/src/index.ts
@@ -103,7 +103,7 @@ export default class IpcProvider exte
this._socketConnection.connect({ path: this._socketPath });
}
- protected _closeSocketConnection(code?: number, data?: string) {
+ protected _closeSocketConnection(code: number, data?: string) {
this._socketConnection?.end(() => {
this._onDisconnect(code, data);
});
diff --git a/packages/web3-utils/src/socket_provider.ts b/packages/web3-utils/src/socket_provider.ts
index 3e0e4bd4bae..b8124b18ed6 100644
--- a/packages/web3-utils/src/socket_provider.ts
+++ b/packages/web3-utils/src/socket_provider.ts
@@ -312,7 +312,7 @@ export abstract class SocketProvider<
this._eventEmitter.removeListener(type, listener);
}
- protected _onDisconnect(code?: number, data?: string) {
+ protected _onDisconnect(code: number, data?: string) {
this._connectionStatus = 'disconnected';
super._onDisconnect(code, data);
}
diff --git a/packages/web3-utils/src/web3_eip1193_provider.ts b/packages/web3-utils/src/web3_eip1193_provider.ts
index 8d9b9385305..15f132f6215 100644
--- a/packages/web3-utils/src/web3_eip1193_provider.ts
+++ b/packages/web3-utils/src/web3_eip1193_provider.ts
@@ -24,6 +24,7 @@ import {
Web3BaseProvider,
} from 'web3-types';
import { EventEmitter } from 'events';
+import { EIP1193ProviderRpcError } from 'web3-errors';
import { toPayload } from './json_rpc.js';
/**
@@ -104,11 +105,8 @@ export abstract class Eip1193Provider<
}
// todo this must be ProvideRpcError with a message too
- protected _onDisconnect(code?: number, data?: unknown) {
- this._eventEmitter.emit('disconnect', {
- code,
- data,
- });
+ protected _onDisconnect(code: number, data?: unknown) {
+ this._eventEmitter.emit('disconnect', new EIP1193ProviderRpcError(code, data));
}
private _onAccountsChanged() {
diff --git a/packages/web3/test/integration/web3.accounts.test.ts b/packages/web3/test/integration/web3.accounts.test.ts
index 021baccb712..22a0c83a8c1 100644
--- a/packages/web3/test/integration/web3.accounts.test.ts
+++ b/packages/web3/test/integration/web3.accounts.test.ts
@@ -63,7 +63,7 @@ describe('web3.accounts', () => {
const tx = {
from: account.address,
to: tempAccount,
- value: web3.utils.toWei('0.1', 'ether'),
+ value: web3.utils.toWei('0.00001', 'ether'),
gas: '0x5218',
data: '0x1',
};
@@ -73,7 +73,7 @@ describe('web3.accounts', () => {
web3.eth.sendTransaction({
from: tempAccount,
to: account.address,
- value: web3.utils.toWei('0.5', 'ether'),
+ value: web3.utils.toWei('0.00005', 'ether'),
}),
).resolves.toBeDefined();