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.
Turns out the "err" inside the function call is not working. I have to use this way instead in order to catch that error.
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
});
}
})
.catch((err: any) => {
// Handle the error here
reject();
})