I was trying to catch the error thrown by the web3.js during the calling of a function in my smart contract. This is the code I use for calling the function:
contract.methods.mintBatch(quantity, data.nonce, data.hash, data.signature, data.nftIds, 1).send({ from: walletId, value: res * quantity }, (err: any, res: any) => {
if (err) {
console.error('mintBatch failed, error: ', err);
reject();
}
else {
console.log('mintBatch succeed, res: ', res);
resolve({
txHash: res,
nftIds: data.nftIds
});
}
})
And this is the function I use to keep tracking the status of a transaction:
function checkIfTransactionProceed(txHash: string) {
return new Promise<void>(async (resolve, reject) => {
var receipt = null;
var counter = 0;
try {
while ((receipt = await web3.eth.getTransactionReceipt(txHash)) === null) {
if (counter++ > 300) {
break;
}
await new Promise<void>(resolve2 => {
setTimeout(() => {
resolve2();
}, 1000);
});
}
if (receipt && (receipt.status === true)) {
resolve();
}
else {
reject();
}
}
catch(err) {
console.error('web3.eth.getTransactionReceipt failed, error: ', err);
reject();
}
})
}
The second one works perfectly, and it will throw an error when the transaction fails. But right after that error is thrown, this is given by my react frontend:
Unhandled Runtime Error
Error: Transaction has been reverted by the EVM:
{
"blockHash": "0x2d7a0a4e5469e68250eaee0c52eb80559d6f9e2a8873ab4f7b2f47e5e9b973b3",
"blockNumber": 11284056,
"contractAddress": null,
"cumulativeGasUsed": 368714,
"effectiveGasPrice": 2500000009,
"from": "somewhere",
"gasUsed": 76047,
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"status": false,
"to": "somewhere else",
"transactionHash": "a random transaction hash",
"transactionIndex": 2,
"type": "0x2",
"events": {}
}
By tracking the error, it seems the error comes from a function called _fireError
inside the web3.js.
var _fireError = function (error, emitter, reject, callback, optionalData) {
/*jshint maxcomplexity: 10 */
// add data if given
if (!!error && typeof error === 'object' && !(error instanceof Error) && error.data) {
if (!!error.data && typeof error.data === 'object' || Array.isArray(error.data)) {
error.data = JSON.stringify(error.data, null, 2);
}
error = error.message + "\n" + error.data;
}
if (typeof error === 'string') {
error = new Error(error);
}
if (typeof callback === 'function') {
callback(error, optionalData);
}
if (typeof reject === 'function') {
// suppress uncatched error if an error listener is present
// OR suppress uncatched error if an callback listener is present
if (emitter &&
(typeof emitter.listeners === 'function' &&
emitter.listeners('error').length) || typeof callback === 'function') {
emitter.catch(function () { });
}
// reject later, to be able to return emitter
setTimeout(function () {
reject(error);
}, 1);
}
if (emitter && typeof emitter.emit === 'function') {
// emit later, to be able to return emitter
setTimeout(function () {
emitter.emit('error', error, optionalData);
emitter.removeAllListeners();
}, 1);
}
return emitter;
};
Can anyone let me know how to catch that error? It doesn't trigger any catcher on my end, and that "mintBatch failed" isn't shown either.