Skip to content

Commit

Permalink
sendTransaction and sendSignedTransaction Error Refactors (#5854)
Browse files Browse the repository at this point in the history
* Add payload as optional argument for InvalidResponseError

* Init Transaction Error Scenarios tests

* Init ERR_TX_REVERT_TRANSACTION_CUSTOM_ERROR

* WIP

* WIP

* Update TransactionRevertedWithoutReasonError to handle receipts objects with BigInts

* Update sendTransaction revert tests

* Add contractAbi argument to getTransactionError

* sendTransation emits error for ContractExecutionError

* Add ContractExecutionError to SendTransactionEvents. Add contractAbi to SendTransactionOptions

* Replace use of contractExecutionError sendTransaction event with error

* Update contract_methods reverts test

* Update web3-errors test

* Update expected error mesage for contract_deploy_test

* Add expectedErrorObject based on test backend

* Correct web3-errors test snapshots

* fix (#5869)

* 5747 codecov (#5843)

* code cov integration for unit tests

* removed cov threshold

* code cov token

* by default collect coverage

* codecov with existing unittests

* jest config

* only analyze coverage for n v16 unit test runs

* node ver

* codecov paths config

* added layout

* common config

* flag names in ci

* flags under proj

* min CI for test

* build and test for u14 and 16

* validated yml

* components usage

* comment moved at end

* updated comments

* testing 90% cov target

* component cov target

* patch cov

* enable actions + remove old coverage check actions

* codecov config change

* remove unused scripts

* ens system tests (#5849)

* Expose registry events in ens class

* Add tests for events

* Check for socket

* Skip test

* Try to unskip test

* skip test again

* Update packages/web3-eth-ens/test/integration/ens.events.test.ts

Co-authored-by: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com>

* feedback

---------

Co-authored-by: Junaid <86780488+jdevcs@users.noreply.github.com>
Co-authored-by: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com>

* Disconnect function doesn't exists in types of currentProvider (#5865)

* fix disconnect function

* add link

* test types

* add disconnect function test

* fix eth tests

* test stuck

* trace

* fix

* check

* fix test

* add empty disconnect function

* add test for provider instances

* fix http unit test

* remove logs

* revert to throw error http provider

---------

Co-authored-by: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com>

* Nikos/fix ens event test (#5880)

* Expose registry events in ens class

* Add tests for events

* Check for socket

* Skip test

* Try to unskip test

* skip test again

* Update packages/web3-eth-ens/test/integration/ens.events.test.ts

Co-authored-by: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com>

* feedback

* Try fix

* Merge branch '4.x'

* Revert conf files

* Remove error for event

---------

Co-authored-by: Junaid <86780488+jdevcs@users.noreply.github.com>
Co-authored-by: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com>

* update event emitter geth ipc tests (#5874)

* update geth binary tests

* update helper and changelog

* adding await

* update helper

* add await

* add await

* add await

* fix typings

* update tests

* update

* debug

* remove debugging

* 4.x issue stale conf (#5878)

* Add documentation for catching provider events (#5886)

* show Ipc and WebSocket providers in the documentation

* add guides for providers and their events

* move the generic section of the providers guide from the migration guide

* edit some texts in the guides

* Fixing tests for WS and IPC

* Remove jest specific test code that doesn't work in Cypress

* Remove jest specific test code that doesn't work in Cypress

* Remove jest specific test code

* Add toLowerCase for address

* Rename TransactionRevertError to TransactionRevertInstructionError

* Add beforeAll for Transaction Error Scenario tests

* Add Transaction Error Scenario tests for call

* Add support for handleRevert in sendTransaction for geth

* Update tests and add test to verify event error is same as thrown error

* Correct test expected data

* Remove message from expectedThrownError for sendTransaction tests

* Add error refactors to sendSignedTransaction and init tests

* Remove call Transaction Error Scenario tests

* Fix type error

* Fix nonce issue in tests

* Fix error parsing bug for web3Eth.sendSignedTransaction

* Update expected error for send_signed_transaction error tests

* Revert ResponseError change to maintain 1.x parity

* Add web3-errors test for TransactionRevertWithCustomError

* Update expected error message for RespnoseError in web3-eth-contract tests

* Add example to dev comment for sendSignedTransaction

* Removed implemented TODO in packages/web3-eth/src/utils/get_transaction_error.ts

* Update CHANGELOGs

* Update CHANGELOG.md

* Init get_transaction_error tests

* Add mock to getRevertReason for get_transaction_error tests

* Init getRevertReason tests and parseTransactionError tests

* Add check for revert before sending tx

* Update web3-plugin-example test to account for getRevertReason check

* Turn off checkRevertBeforeSending for sendFewTxes helper

* Fix test data for send_signed_transaction tests

* Fix bug in get_transaction_error

* Fix send_transaction error test

* Add checkRevertBeforeSending: false to sendTransaction calls in Contract class

* Add checkRevertBeforeSending: false for send tx test helpers

* Remove getRevertReason mock

* A fix at `IpcProvider` and few changes at `SocketProvider` and its descendants (#5891)

* rename `_providerOptions` to `_socketOptions`

* pass `_socketOptions` from IpcProvider constructor to the underlying connection

* move a comment to its correct position at `SocketProvider`

* expose the getter of `SocketConnection` from `SocketProvider`.

* update CHANGELOG.md files

* add extremely simple unit test for SocketProvider

* Fix failed tx test for ganache

* Update expected transaction errors for ganache

* Fix method handler crashed (#5905)

* version fix

* use geth binary

* try 1.11.2

* Test fix

* Use `v1` instead of Short Sha for cloudflare/pages-action (#5909)

* use `v1` instead of short Sha for cloudflare/pages-action

---------

Co-authored-by: Oleksii Kosynskyi <oleksii.kosynskyi@gmail.com>
Co-authored-by: Junaid <86780488+jdevcs@users.noreply.github.com>
Co-authored-by: Nikos Iliakis <nikoulai@users.noreply.github.com>
Co-authored-by: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com>
Co-authored-by: Alex <alex.luu@mail.utoronto.ca>
  • Loading branch information
6 people authored Mar 9, 2023
1 parent 7a9c2bb commit f758099
Show file tree
Hide file tree
Showing 29 changed files with 1,648 additions and 212 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1155,11 +1155,15 @@ should use 4.0.1-alpha.0 for testing.
#### web3-errors

- Added error class `InvalidMethodParamsError` and error code `ERR_INVALID_METHOD_PARAMS = 207` (#5824)
- `request` property to `ResponseError` (#5854)
- `data` property to `TransactionRevertInstructionError` (#5854)
- `TransactionRevertWithCustomError` was added to handle custom solidity errors (#5854)

#### web3-eth

- Added `createAccessList` functionality ( #5780 )
- Added support of `safe` and `finalized` block tags (#5823)
- `contractAbi` option to `SendTransactionOptions` and `SendSignedTransactionOptions` to added the ability to parse custom solidity errors (#5854)

#### web3-eth-abi

Expand Down Expand Up @@ -1211,10 +1215,12 @@ should use 4.0.1-alpha.0 for testing.
#### web3-errors

- The abstract class `Web3Error` is renamed to `BaseWeb3Error` (#5771)
- Renamed `TransactionRevertError` to `TransactionRevertInstructionError` to remain consistent with `1.x` (#5854)

#### web3-eth

- Update imports statements for objects that was moved between web3 packages (#5771)
- `sendTransaction` and `sendSignedTransaction` now errors with (and `error` event emits) the following possible errors: `TransactionRevertedWithoutReasonError`, `TransactionRevertInstructionError`, `TransactionRevertWithCustomError`, `InvalidResponseError`, or `ContractExecutionError` (#5854)

#### web3-eth-contract

Expand Down Expand Up @@ -1257,3 +1263,4 @@ should use 4.0.1-alpha.0 for testing.
#### web3-eth-contract

- Fix contract defaults (#5756)
- Fixed getPastEventsError (#5819)
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,4 @@ provider.on('error', error => {
// the `maxAttempts` is equal to the provided value by the user, or the default value `5`.
}
});
```
```
2 changes: 1 addition & 1 deletion docs/docs/guides/web3_providers_guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,4 +207,4 @@ provider.on('error', error => {
// the `maxAttempts` is equal to the provided value by the user, or the default value `5`.
}
});
```
```
2 changes: 1 addition & 1 deletion packages/web3-core/src/web3_request_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ export class Web3RequestManager<
throw new RpcError(rpcErrorResponse);
}
} else if (!Web3RequestManager._isReverted(response)) {
throw new InvalidResponseError<ErrorType>(response);
throw new InvalidResponseError<ErrorType, RequestType>(response, payload);
}
}

Expand Down
4 changes: 4 additions & 0 deletions packages/web3-errors/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- The abstract class `Web3Error` is renamed to `BaseWeb3Error` (#5771)
- Renamed TransactionRevertError to TransactionRevertInstructionError to remain consistent with 1.x
- Using `MaxAttemptsReachedOnReconnectingError` with the same message for 1.x but also adding the `maxAttempts` (#5894)

### Added

- Added error class `InvalidMethodParamsError` and error code `ERR_INVALID_METHOD_PARAMS = 207` (#5824)
- `request` property to `ResponseError` (#5854)
- `data` property to `TransactionRevertInstructionError` (#5854)
- `TransactionRevertWithCustomError` was added to handle custom solidity errors (#5854)
1 change: 1 addition & 0 deletions packages/web3-errors/src/error_codes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export const ERR_TX_GAS_MISMATCH = 434;
export const ERR_TX_CHAIN_MISMATCH = 435;
export const ERR_TX_HARDFORK_MISMATCH = 436;
export const ERR_TX_INVALID_RECEIVER = 437;
export const ERR_TX_REVERT_TRANSACTION_CUSTOM_ERROR = 438;

// Connection error codes
export const ERR_CONN = 500;
Expand Down
32 changes: 25 additions & 7 deletions packages/web3-errors/src/errors/response_errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/

// eslint-disable-next-line max-classes-per-file
import { JsonRpcError, JsonRpcResponse, JsonRpcResponseWithError } from 'web3-types';
import {
JsonRpcError,
JsonRpcPayload,
JsonRpcResponse,
JsonRpcResponseWithError,
} from 'web3-types';
import { BaseWeb3Error } from '../web3_error_base';
import { ERR_INVALID_RESPONSE, ERR_RESPONSE } from '../error_codes';

Expand All @@ -36,11 +41,16 @@ const isResponseWithError = <Error = unknown, Result = unknown>(
const buildErrorMessage = (response: JsonRpcResponse<unknown, unknown>): string =>
isResponseWithError(response) ? response.error.message : '';

export class ResponseError<ErrorType = unknown> extends BaseWeb3Error {
export class ResponseError<ErrorType = unknown, RequestType = unknown> extends BaseWeb3Error {
public code = ERR_RESPONSE;
public data?: ErrorType | ErrorType[];
public request?: JsonRpcPayload<RequestType>;

public constructor(response: JsonRpcResponse<unknown, ErrorType>, message?: string) {
public constructor(
response: JsonRpcResponse<unknown, ErrorType>,
message?: string,
request?: JsonRpcPayload<RequestType>,
) {
super(
message ??
`Returned error: ${
Expand All @@ -55,16 +65,24 @@ export class ResponseError<ErrorType = unknown> extends BaseWeb3Error {
? response.map(r => r.error?.data as ErrorType)
: response?.error?.data;
}

this.request = request;
}

public toJSON() {
return { ...super.toJSON(), data: this.data };
return { ...super.toJSON(), data: this.data, request: this.request };
}
}

export class InvalidResponseError<ErrorType = unknown> extends ResponseError<ErrorType> {
public constructor(result: JsonRpcResponse<unknown, ErrorType>) {
super(result);
export class InvalidResponseError<ErrorType = unknown, RequestType = unknown> extends ResponseError<
ErrorType,
RequestType
> {
public constructor(
result: JsonRpcResponse<unknown, ErrorType>,
request?: JsonRpcPayload<RequestType>,
) {
super(result, undefined, request);
this.code = ERR_INVALID_RESPONSE;

let errorOrErrors: JsonRpcError | JsonRpcError[] | undefined;
Expand Down
59 changes: 53 additions & 6 deletions packages/web3-errors/src/errors/transaction_errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import {
ERR_TX_UNABLE_TO_POPULATE_NONCE,
ERR_TX_UNSUPPORTED_EIP_1559,
ERR_TX_UNSUPPORTED_TYPE,
ERR_TX_REVERT_TRANSACTION_CUSTOM_ERROR,
} from '../error_codes';
import { InvalidValueError, BaseWeb3Error } from '../web3_error_base';

Expand Down Expand Up @@ -84,16 +85,21 @@ export class RevertInstructionError extends BaseWeb3Error {
}
}

export class TransactionRevertError extends BaseWeb3Error {
export class TransactionRevertInstructionError<
ReceiptType = TransactionReceipt,
> extends BaseWeb3Error {
public code = ERR_TX_REVERT_TRANSACTION;

public constructor(
public reason: string,
public signature?: string,
public receipt?: TransactionReceipt,
public receipt?: ReceiptType,
public data?: string,
) {
super(
`Transaction has been reverted by the EVM:\n ${JSON.stringify(receipt, undefined, 2)}`,
`Transaction has been reverted by the EVM${
receipt === undefined ? '' : `:\n ${BaseWeb3Error.convertToString(receipt)}`
}`,
);
}

Expand All @@ -103,6 +109,43 @@ export class TransactionRevertError extends BaseWeb3Error {
reason: this.reason,
signature: this.signature,
receipt: this.receipt,
data: this.data,
};
}
}

/**
* This error is used when a transaction to a smart contract fails and
* a custom user error (https://blog.soliditylang.org/2021/04/21/custom-errors/)
* is able to be parsed from the revert reason
*/
export class TransactionRevertWithCustomError<
ReceiptType = TransactionReceipt,
> extends TransactionRevertInstructionError<ReceiptType> {
public code = ERR_TX_REVERT_TRANSACTION_CUSTOM_ERROR;

public constructor(
public reason: string,
public customErrorName: string,
public customErrorDecodedSignature: string,
public customErrorArguments: Record<string, unknown>,
public signature?: string,
public receipt?: ReceiptType,
public data?: string,
) {
super(reason);
}

public toJSON() {
return {
...super.toJSON(),
reason: this.reason,
customErrorName: this.customErrorName,
customErrorDecodedSignature: this.customErrorDecodedSignature,
customErrorArguments: this.customErrorArguments,
signature: this.signature,
receipt: this.receipt,
data: this.data,
};
}
}
Expand All @@ -125,10 +168,14 @@ export class ContractCodeNotStoredError extends TransactionError {
}
}

export class TransactionRevertedWithoutReasonError extends TransactionError {
public constructor(receipt: TransactionReceipt) {
export class TransactionRevertedWithoutReasonError<
ReceiptType = TransactionReceipt,
> extends TransactionError<ReceiptType> {
public constructor(receipt?: ReceiptType) {
super(
`Transaction has been reverted by the EVM:\n ${JSON.stringify(receipt, undefined, 2)}`,
`Transaction has been reverted by the EVM${
receipt === undefined ? '' : `:\n ${BaseWeb3Error.convertToString(receipt)}`
}`,
receipt,
);
this.code = ERR_TX_REVERT_WITHOUT_REASON;
Expand Down
36 changes: 28 additions & 8 deletions packages/web3-errors/test/unit/__snapshots__/errors.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ Object {
},
"message": "Returned error: error message",
"name": "InvalidResponseError",
"request": undefined,
}
`;

Expand Down Expand Up @@ -229,6 +230,7 @@ Object {
"innerError": undefined,
"message": "Returned error: error message",
"name": "ResponseError",
"request": undefined,
}
`;

Expand All @@ -239,6 +241,7 @@ Object {
"innerError": undefined,
"message": "Returned error: error message",
"name": "ResponseError",
"request": undefined,
}
`;

Expand Down Expand Up @@ -280,15 +283,14 @@ Object {
}
`;

exports[`errors TransactionRevertError should have valid json structure 1`] = `
exports[`errors TransactionRevertInstructionError should have valid json structure 1`] = `
Object {
"code": 402,
"data": undefined,
"innerError": undefined,
"message": "Transaction has been reverted by the EVM:
{
\\"attr1\\": \\"attr1\\"
}",
"name": "TransactionRevertError",
{\\"attr1\\":\\"attr1\\"}",
"name": "TransactionRevertInstructionError",
"reason": "message",
"receipt": Object {
"attr1": "attr1",
Expand All @@ -297,14 +299,32 @@ Object {
}
`;

exports[`errors TransactionRevertWithCustomError should have valid json structure 1`] = `
Object {
"code": 438,
"customErrorArguments": Object {
"customErrorArgument": "customErrorArgument",
},
"customErrorDecodedSignature": "customErrorDecodedSignature",
"customErrorName": "customErrorName",
"data": "data",
"innerError": undefined,
"message": "Transaction has been reverted by the EVM",
"name": "TransactionRevertWithCustomError",
"reason": "reason",
"receipt": Object {
"attr1": "attr1",
},
"signature": "signature",
}
`;

exports[`errors TransactionRevertedWithoutReasonError should have valid json structure 1`] = `
Object {
"code": 405,
"innerError": undefined,
"message": "Transaction has been reverted by the EVM:
{
\\"attr1\\": \\"attr1\\"
}",
{\\"attr1\\":\\"attr1\\"}",
"name": "TransactionRevertedWithoutReasonError",
"receipt": Object {
"attr1": "attr1",
Expand Down
24 changes: 21 additions & 3 deletions packages/web3-errors/test/unit/errors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe('errors', () => {
// To disable error for the abstract class

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
const err = new ErrorClass({} as never, {} as never, {} as never);
const err = new ErrorClass({} as never, {} as never, {} as never, {} as never);
errorCodes.push(err.code);
}

Expand Down Expand Up @@ -162,16 +162,34 @@ describe('errors', () => {
});
});

describe('TransactionRevertError', () => {
describe('TransactionRevertInstructionError', () => {
it('should have valid json structure', () => {
expect(
new transactionErrors.TransactionRevertError('message', 'signature', {
new transactionErrors.TransactionRevertInstructionError('message', 'signature', {
attr1: 'attr1',
} as any).toJSON(),
).toMatchSnapshot();
});
});

describe('TransactionRevertWithCustomError', () => {
it('should have valid json structure', () => {
expect(
new transactionErrors.TransactionRevertWithCustomError(
'reason',
'customErrorName',
'customErrorDecodedSignature',
{ customErrorArgument: 'customErrorArgument' },
'signature',
{
attr1: 'attr1',
} as any,
'data',
).toJSON(),
).toMatchSnapshot();
});
});

describe('NoContractAddressFoundError', () => {
it('should have valid json structure', () => {
expect(
Expand Down
9 changes: 7 additions & 2 deletions packages/web3-eth-contract/src/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1050,10 +1050,13 @@ export class Contract<Abi extends ContractAbi>
options,
contractOptions: modifiedContractOptions,
});
const transactionToSend = sendTransaction(this, tx, DEFAULT_RETURN_FORMAT);
const transactionToSend = sendTransaction(this, tx, DEFAULT_RETURN_FORMAT, {
// TODO Should make this configurable by the user
checkRevertBeforeSending: false,
});

// eslint-disable-next-line no-void
void transactionToSend.on('contractExecutionError', (error: unknown) => {
void transactionToSend.on('error', (error: unknown) => {
if (error instanceof ContractExecutionError) {
// this will parse the error data by trying to decode the ABI error inputs according to EIP-838
decodeContractErrorData(errorsAbi, error.innerError);
Expand Down Expand Up @@ -1094,6 +1097,8 @@ export class Contract<Abi extends ContractAbi>
newContract.options.address = receipt.contractAddress;
return newContract;
},
// TODO Should make this configurable by the user
checkRevertBeforeSending: false,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ describe('contract defaults (extra)', () => {
}),
expect.any(Object),
expect.any(Object),
expect.any(Object),
);
});

Expand Down
Loading

0 comments on commit f758099

Please sign in to comment.