How to catch errors and handle them in a Solidity smart contract

In this tutorial, we are going to learn how to catch errors and handle them using try and catch in a Solidity smart contract.

In this tutorial, we are going to learn how to catch errors and handle them using try and catch in a Solidity smart contract.

To catch and handle errors, you can use a try ... catch block where you will put the code that might throw an error in the try part and the code to execute when an error happens in the catch part.

Here is an example:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

contract ContractA {
    function testFunction(uint x) public pure returns (uint) {
        require(x != 0, "x must not be 0");
        return x;
    }
}

contract ContractB {
    function anotherTestFunction(uint y) public pure {
        ContractA contractA = new ContractA();
        try contractA.testFunction(y) returns (uint result) {
            return result + y + 1;
        } catch {
            return y + 2;
        }
    }
}

In the example above, the ContractB calls the testFunction of ContractA in a try statement when anotherTestFunction is called.

So we try calling contractA.testFunction by saying:

try contractA.testFunction(y) returns (uint result)

and if it doesn't revert, it will execute the code inside the try block, otherwise it will execute what's inside the catch part.

In the code above, the value that contractA.testFunction returns is going to be in the result variable and you can use it inside the try statement like we did.

If you want to get the reason why the function you called reverted, you can add a parameter to the catch block:

try contractA.testFunction(y) returns (uint result) {
    // ...
} catch Error(string memory reason) {
    // ...
}

In the code above, the message returned when the function reverts is going to be contained in the reason variable and you can use it in the catch block.

You can chain multiple catch blocks that will each catch a different error.

Let's say you have a function that returns 2 types of errors, either a uint through an assert or a string through a require. You can catch both types of errors like that:

try contract.myFunc() returns (uint result) {
    // ...
} catch Error(string memory reason) {
    // ...
} catch (uint error) {
    // ...
}

And that's it 🎉

Thank you for reading this article