Close Menu
    Track all markets on TradingView
    Facebook X (Twitter) Instagram
    • Privacy Policy
    • Term And Conditions
    • Disclaimer
    • About us
    • Contact us
    Facebook X (Twitter) Instagram
    WSJ-Crypto
    • Home
    • Bitcoin
    • Ethereum
    • Blockchain
    • Crypto Mining
    • Economy and markets
    WSJ-Crypto
    Home » Unlocking Error Handling in Solidity 0.6.x: The Power of Try/Catch Statements
    Ethereum

    Unlocking Error Handling in Solidity 0.6.x: The Power of Try/Catch Statements

    wsjcryptoBy wsjcrypto24 Gennaio 2025Nessun commento4 Mins Read
    Share
    Facebook Twitter LinkedIn Pinterest Email

    The try/catch syntax unveiled in 0.6.0 is arguably the most significant advancement in error management functionalities in Solidity, since reason strings for revert and require were introduced in v0.4.22. Both try and catch have been designated keywords since v0.5.9 and now we can leverage them to manage failures in external function transactions without reverting the entire transaction (state changes in the invoked function are still reverted, but those in the invoking function are preserved).

    We are taking a step away from the strict “all-or-nothing” paradigm in a transaction lifecycle, which often does not align with the practical behaviour we usually desire.

    Managing external call failures

    The try/catch statement enables you to respond to unsuccessful external calls and contract creation attempts, hence it cannot be utilized for internal function calls. Keep in mind that to enclose a public function call within the same contract with try/catch, it can be executed externally by invoking the function with this..

    The illustration below shows how try/catch is implemented in a factory model where contract creation may encounter failure. The following CharitySplitter contract necessitates a required address attribute _owner in its constructor.

    pragma solidity ^0.6.1;
    
    contract CharitySplitter {
        address public owner;
        constructor (address _owner) public {
            require(_owner != address(0), "no-owner-provided");
            owner = _owner;
        }
    }
    

    There exists a factory contract — CharitySplitterFactory which facilitates the creation and oversight of instances of CharitySplitter. Within the factory, we can encapsulate the new CharitySplitter(charityOwner) within a try/catch as a precaution in case that constructor fails due to an absent charityOwner.

    pragma solidity ^0.6.1;
    import "./CharitySplitter.sol";
    contract CharitySplitterFactory {
        mapping (address => CharitySplitter) public charitySplitters;
        uint public errorCount;
        event ErrorHandled(string reason);
        event ErrorNotHandled(bytes reason);
        function createCharitySplitter(address charityOwner) public {
            try new CharitySplitter(charityOwner)
                returns (CharitySplitter newCharitySplitter)
            {
                charitySplitters[msg.sender] = newCharitySplitter;
            } catch {
                errorCount++;
            }
        }
    }
    

    Please note that within try/catch, only exceptions that occur inside the external invocation itself are captured. Issues occurring within the expression are not captured; for instance, if the input parameter for the new CharitySplitter is a part of an internal call, any issues it generates will not be captured. An example illustrating this behavior is the altered createCharitySplitter function. In this instance, the CharitySplitter constructor input parameter is sourced dynamically from another function — getCharityOwner. If that function fails, in this case with “revert-required-for-testing”, that will not be captured in the try/catch block.

    function createCharitySplitter(address _charityOwner) public {
        try new CharitySplitter(getCharityOwner(_charityOwner, false))
            returns (CharitySplitter newCharitySplitter)
        {
            charitySplitters[msg.sender] = newCharitySplitter;
        } catch (bytes memory reason) {
            ...
        }
    }
    function getCharityOwner(address _charityOwner, bool _toPass)
            internal returns (address) {
        require(_toPass, "revert-required-for-testing");
        return _charityOwner;
    }
    

    Retrieving the error message

    We can further enhance the try/catch mechanism within the createCharitySplitter function to obtain the error message if one was triggered by a failing revert or require and emit it in an event. There are two methods to accomplish this:

    1. Using catch Error(string memory reason)

    function createCharitySplitter(address _charityOwner) public {
        try new CharitySplitter(_charityOwner) returns (CharitySplitter newCharitySplitter)
        {
            charitySplitters[msg.sender] = newCharitySplitter;
        }
        catch Error(string memory reason)
        {
            errorCount++;
            CharitySplitter newCharitySplitter = new
                CharitySplitter(msg.sender);
            charitySplitters[msg.sender] = newCharitySplitter;
            // Emitting the error in event
            emit ErrorHandled(reason);
        }
        catch
        {
            errorCount++;
        }
    }
    

    Which triggers the subsequent event on a failed constructor require error:

    CharitySplitterFactory.ErrorHandled(
        reason: 'no-owner-provided' (type: string)
    )
    

    2. Using catch (bytes memory reason)

    function createCharitySplitter(address charityOwner) public {
        try new CharitySplitter(charityOwner)
            returns (CharitySplitter newCharitySplitter)
        {
            charitySplitters[msg.sender] = newCharitySplitter;
        }
        catch (bytes memory reason) {
            errorCount++;
            emit ErrorNotHandled(reason);
        }
    }
    

    This emits the subsequent event during a failed constructor require mistake:

    CharitySplitterFactory.ErrorNotHandled(
      reason: hex'08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000116e6f2d6f776e65722d70726f7669646564000000000000000000000000000000' (type: bytes)
    

    The preceding two approaches for obtaining the error string yield a comparable outcome. The distinction is that the latter method does not ABI-decode the error string. The benefit of the latter method is that it also executes if ABI decoding the error string is unsuccessful or if no reason was supplied.

    Future intentions

    There are intentions to introduce support for error categories, meaning we will be able to declare errors in a way similar to events, enabling us to catch various types of errors, for instance:

    catch CustomErrorA(uint data1) { … }
    catch CustomErrorB(uint[] memory data2) { … }
    catch {}
    



    Source link

    return a list of comma separated tags from this title: Solidity 0.6.x features: try/catch statement
    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
    wsjcrypto

    Related Posts

    Bringing Ethereum Back Together as One Chain

    18 Novembre 2025

    Navigating the Future: Insights from Checkpoint #7 – November 2025

    15 Novembre 2025

    Fusaka Mainnet Launch: A New Era for Ethereum Enthusiasts

    6 Novembre 2025

    Countdown to Devconnect: Your Essential Guide for the Next Two Weeks

    4 Novembre 2025
    Add A Comment

    Comments are closed.

    Top Posts

    Subscribe to Updates

    Get the latest sports news from SportsSite about soccer, football and tennis.

    Top Coins
    # Name Price Changes 24h Market CAPVolumeSupply
    WSJ-Crypto
    Facebook X (Twitter) Instagram Pinterest
    • Privacy Policy
    • Term And Conditions
    • Disclaimer
    • About us
    • Contact us
    ©Copyright 2025 . Designed by WSJ-Crypto

    Type above and press Enter to search. Press Esc to cancel.

    Go to mobile version