I wrote an article in my blog about this topic.
Using Web3.js to Parse Custom Error. It includes call, estimateGas and tx error. It should be helpful.
In your case, you can use this function to parse custom error.
import { Eip838ExecutionError } from 'web3';
import { decodeContractErrorData } from 'web3-eth-abi';
function parseInnerError(e, contract) {
if (e?.innerError?.errorSignature) {
return e.innerError;
}
if (!e.innerError) {
if (e?.data?.data.startsWith('0x')) {
e.innerError = new Eip838ExecutionError(e.data);
}
}
if (e?.innerError?.data?.startsWith('0x')) {
decodeContractErrorData(contract._errorsInterface, e.innerError);
}
return e.innerError;
}
And usage will be
try {
await myContract.methods.sendWithError().estimateGas({ from });
} catch (e) {
const innerError = parseInnerError(e, myContract);
}
Notice: RPC Node should also support custom error. For example, Arbitrum Goerli supports, but Ganache v2.5.4 not.
Tested at Web3.js v4.0.1 and Arbitrum Goerli.