Search code examples
ethereumblockchainsoliditysmartcontracts

How can I catch smart contract exception from web3


I am using web3-react to build Web UI which interacts with smart contract running in Ethereum Ganache network.

The contract has a method to create a sector in solidty:

function createSector(uint256 x, uint256 y, uint256 width, uint256 height) public payable {
    uint256 price = _calculateSectorPrice(width, height);
    Sector memory sector = Sector(x, y, width, height, price);
    require(balanceOf(msg.sender) + msg.value >= price, "Insufficient funds");
    ...
  }

when the web calls this method, the require throws an error: Insufficient funds. But the UI doesn't get this specific error, instead it gets ContractExecutionError: Error happened while trying to execute a function inside a smart contract. This error is too generic because it doesn't tell what the real error is.

The web3 code I have is:

await contract.methods
            .createSector(
              web3.utils.toBigInt(selectedCells[0].globalI),
              web3.utils.toBigInt(selectedCells[0].globalJ),
              web3.utils.toBigInt(1),
              web3.utils.toBigInt(1),
              { value: web3.utils.fromWei(cellPriceInWei, 'ether') }
            )
            .send({ from: account.address });

I can confirm that if I remove the require from smart contract, everything works fine. My question is how to catch the error from smart contract?


Solution

  • In try/catch, catch block would catch any error. "Insufficient fund" has specific error code:

    const callCreateSector = () => {
      try {
        await contract.methods
          .createSector(
            web3.utils.toBigInt(selectedCells[0].globalI),
            web3.utils.toBigInt(selectedCells[0].globalJ),
            web3.utils.toBigInt(1),
            web3.utils.toBigInt(1),
            { value: web3.utils.fromWei(cellPriceInWei, "ether") }
          )
          .send({ from: account.address });
      } catch (error) {
        if (error.code === -32603 && error.data.code === -32000) {
          // This was your error code
          console.error("Write error message because of insufficient funds ...");
        }
      }
    };