Back
Lesson 17:
 Try/Catch
Introduction to Try/Catch and how to use it in your smart contracts.
Progress: 0%
Visit desktop version for better experiences.
Try/Catch
A failure in an external call can be gracefully caught using a try/catch statement.
The try keyword has to be followed by an external function call.
Solidity also supports various catch blocks to handle different types of exceptions:
catch Error(string memory reason)to catch failingrevert()andrequire()catch Panic(uint256 panicCode){...}to catch failing panic error, i.e. failingassert(), division by zero, arithmetic overflow, etc.catch (bytes memory reason){...}to catch error signatures which does not match any other clause. In result, the declared variable returns the low-level error data.catch {...}can be used if you are not interested in the error data.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
// External contract used for try / catch examples
contract ExternalContract {
    address public owner;
    constructor(address _owner) {
        require(_owner != address(0), "Invalid address");
        assert(_owner != 0x0000000000000000000000000000000000000001);
        owner = _owner;
    }
    function performAction(uint256 x) public pure returns (string memory) {
        require(x != 0, "Require failed");
        return "Action performed";
    }
}
contract MainContract {
    event Log(string message);
    event LogBytes(bytes data);
    ExternalContract public externalContract;
    constructor() {
        // This ExternalContract is used for example of try catch with external call
        externalContract = new ExternalContract(msg.sender);
    }
    // Example of try / catch with external call
    // handleExternalCall(0) => Log("External call failed")
    // handleExternalCall(1) => Log("Action performed")
    function handleExternalCall(uint256 _i) public {
        try externalContract.performAction(_i) returns (string memory result) {
            emit Log(result);
        } catch {
            emit Log("External call failed");
        }
    }
    // Example of try / catch with contract creation
    // handleNewContract(0x0000000000000000000000000000000000000000) => Log("Invalid address")
    // handleNewContract(0x0000000000000000000000000000000000000001) => LogBytes("")
    // handleNewContract(0x0000000000000000000000000000000000000002) => Log("ExternalContract created")
    function handleNewContract(address _owner) public {
        try new ExternalContract(_owner) returns (ExternalContract _externalContract) {
            // you can use variable _externalContract here
            emit Log("ExternalContract created");
        } catch Error(string memory reason) {
            // catch failing revert() and require()
            emit Log(reason);
        } catch (bytes memory reason) {
            // catch failing assert()
            emit LogBytes(reason);
        }
    }
}