Skip to content
This repository was archived by the owner on Mar 5, 2025. It is now read-only.

Commit 7b7e5b0

Browse files
Use Error ABI to parse errors when sending a transaction (#5662)
* use Error ABI when sending a transaction * update CHANGELOG.md for #5587
1 parent 21b7649 commit 7b7e5b0

File tree

4 files changed

+30
-12
lines changed

4 files changed

+30
-12
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,10 @@ should use 4.0.1-alpha.0 for testing.
895895

896896
### Added
897897

898+
#### web3-eth-contract
899+
900+
- Decoding error data, using Error ABI if available, if error was returned from a smart contract function call (#5662).
901+
898902
#### web3-types
899903

900904
- These types were moved from `web3-eth-accounts` to `web3-types` package: Cipher, CipherOptions, ScryptParams, PBKDF2SHA256Params, KeyStore (#5581 )

packages/web3-eth-contract/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,10 @@ const transactionHash = receipt.transactionHash;
186186

187187
## [Unreleased]
188188

189+
### Added
190+
191+
- Decoding error data, using Error ABI if available, if error was returned from a smart contract function call (#5662).
192+
189193
### Fixed
190194

191195
- Emit past contract events based on `fromBlock` when passed to `contract.events.someEventName` (#5201)

packages/web3-eth-contract/src/contract.ts

+16-8
Original file line numberDiff line numberDiff line change
@@ -1049,7 +1049,7 @@ export class Contract<Abi extends ContractAbi>
10491049
call: async (options?: PayableCallOptions, block?: BlockNumberOrTag) =>
10501050
this._contractMethodCall(methodAbi, abiParams, errorsAbis, options, block),
10511051
send: (options?: PayableTxOptions) =>
1052-
this._contractMethodSend(methodAbi, abiParams, options), // TODO: refactor to parse errorsAbi #5587
1052+
this._contractMethodSend(methodAbi, abiParams, errorsAbis, options),
10531053
estimateGas: async <
10541054
ReturnFormat extends DataFormat = typeof DEFAULT_RETURN_FORMAT,
10551055
>(
@@ -1073,7 +1073,7 @@ export class Contract<Abi extends ContractAbi>
10731073
call: async (options?: NonPayableCallOptions, block?: BlockNumberOrTag) =>
10741074
this._contractMethodCall(methodAbi, abiParams, errorsAbis, options, block),
10751075
send: (options?: NonPayableTxOptions) =>
1076-
this._contractMethodSend(methodAbi, abiParams, options), // TODO: refactor to parse errorsAbi #5587
1076+
this._contractMethodSend(methodAbi, abiParams, errorsAbis, options),
10771077
estimateGas: async <ReturnFormat extends DataFormat = typeof DEFAULT_RETURN_FORMAT>(
10781078
options?: NonPayableCallOptions,
10791079
returnFormat: ReturnFormat = DEFAULT_RETURN_FORMAT as ReturnFormat,
@@ -1092,13 +1092,10 @@ export class Contract<Abi extends ContractAbi>
10921092
};
10931093
}
10941094

1095-
private async _contractMethodCall<
1096-
E extends AbiErrorFragment,
1097-
Options extends PayableCallOptions | NonPayableCallOptions,
1098-
>(
1095+
private async _contractMethodCall<Options extends PayableCallOptions | NonPayableCallOptions>(
10991096
abi: AbiFunctionFragment,
11001097
params: unknown[],
1101-
errorsAbi: E[],
1098+
errorsAbi: AbiErrorFragment[],
11021099
options?: Options,
11031100
block?: BlockNumberOrTag,
11041101
) {
@@ -1126,6 +1123,7 @@ export class Contract<Abi extends ContractAbi>
11261123
private _contractMethodSend<Options extends PayableCallOptions | NonPayableCallOptions>(
11271124
abi: AbiFunctionFragment,
11281125
params: unknown[],
1126+
errorsAbi: AbiErrorFragment[],
11291127
options?: Options,
11301128
contractOptions?: ContractOptions,
11311129
) {
@@ -1143,7 +1141,17 @@ export class Contract<Abi extends ContractAbi>
11431141
contractOptions: modifiedContractOptions,
11441142
});
11451143

1146-
return sendTransaction(this, tx, DEFAULT_RETURN_FORMAT);
1144+
const promiEvent = sendTransaction(this, tx, DEFAULT_RETURN_FORMAT);
1145+
1146+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
1147+
promiEvent.on('error', (error: unknown) => {
1148+
if (error instanceof ContractExecutionError) {
1149+
// this will parse the error data by trying to decode the ABI error inputs according to EIP-838
1150+
decodeErrorData(errorsAbi, error.innerError);
1151+
}
1152+
});
1153+
1154+
return promiEvent;
11471155
}
11481156

11491157
private _contractMethodDeploySend<Options extends PayableCallOptions | NonPayableCallOptions>(

packages/web3-eth-contract/test/unit/contract.test.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,13 @@ describe('Contract', () => {
157157
) {
158158
// eslint-disable-next-line
159159
expect(_tx.to).toStrictEqual(deployedAddr);
160-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
161-
return Promise.resolve({ status: '0x1' }) as any;
160+
161+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-empty-function
162+
return { status: '0x1', on: () => {} } as any;
162163
}
163-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
164-
return Promise.resolve(newContract) as any;
164+
165+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-empty-function
166+
return Promise.resolve(Object.assign(newContract, { on: () => {} })) as any;
165167
});
166168

167169
const deployedContract = await contract

0 commit comments

Comments
 (0)