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();