Search code examples
reactjssmartcontractsweb3jstruffle

How can catch exception on Smart Contract?


Hello and thank you in advance!

const comprarCapsula = () => {
    const compraCapsula = async () => {

        console.log("Iniciando transacción...");
        // ------------------------
        const pago = web3.utils.toWei(precioFinal.toString(), 'ether');
        // Mensaje de información
        infoAlert();
        // Petición al SC
        const transaction = await contract.myFunction(cantidad, {
            from: props.currentAccount,
            value: pago.toString()}
        ).then((result) => {
            console.log("RESULT:", result);
            successAlert(result.tx);
        }).catch((error) => {
            console.error("TESTING: ", error.message);
            errorAlert(error.message);
        });
        console.log("TRANS: ", transaction);
        // ------------------------
    }

    contract && compraCapsula()
}

My application detects when I cancel the operation with MetaMask (error) but if the Smart Contract throws an error it is not picked up by the catch.

MetaMask - RPC Error: Internal JSON-RPC error. 
Object { code: -32603, message: "Internal JSON-RPC error.", data: {…} }
Data: Object { code: 3, message: "execution reverted: Exception: must have minter role to mint"

Error "must have minter role to mint" its in my Smart Contract.

Why? I'm trying several ways to collect the RPC errors that Metamask throws but I can't find the way.


Solution

  • Could you check calling your contract function as such:

    contract.myFunction.call
    

    rather than

    contract.myFunction
    

    I had a similar problem when developing a contract. call can be used to see whether the function will throw an error - especially structural, modifier checking wise - but only using call will not invoke the full behaviour of the function. After checking for errors with call, you can call the function again.

    Function calls with call enabled us to catch those kind of errors. I used such a structure then:

    await contract.myFunction.call(`parameters...`)
         .then(
                contract.myFunction(`parameters...`)
          )