Back to homepage

Error handling with throw and revert: differences and gas usage

Published

In this article we're going to see different ways to handle errors in Solidity using throw, revert and also require.

Exceptions with throw

In Solidity, you can throw an exception to signal an error condition. This can be done using the throw keyword. For example:

function divide(uint numerator, uint denominator) public {
    if (denominator == 0) {
        throw;
    }
    return numerator / denominator;
}

In this example, the throw statement is used to throw an exception if the denominator is 0, which would cause a division by zero error.

Errors with revert

You can also create and throw your own error messages using the revert keyword. For example:

function sendFunds(address recipient, uint amount) public {
    if (amount > balance) {
        revert("Insufficient funds");
    }
    recipient.transfer(amount);
}

In this example, the revert statement is used to throw an exception with the message "Insufficient funds" if the amount is greater than the current balance of the contract.

Note that both throw and revert will revert any changes made to the contract state and revert the transaction.

require as an alternative

You can also use the require() function to throw a custom error message. require() is similar to revert(), but it is typically used to check for conditions that should never happen, such as invalid input data or situations that should be impossible due to other checks in the contract. Here's an example of how to use it:

function setOwner(address newOwner) public {
    require(newOwner != address(0), "invalid address: 0x0");
    owner = newOwner;
}

In both revert and require examples, the error message that is thrown will be the string that is passed to revert() or require() functions. This message will be included in the transaction revert reason and can be accessed by client libraries and other tools that handle transactions.

throw and revert gas usage

In Solidity, throw is a more expensive operation than revert because it consumes all remaining gas. This means that if a contract calls throw(), all gas provided to the contract will be consumed and no gas will be refunded to the caller.

On the other hand, revert does not consume all remaining gas and instead only consumes the gas used by the revert operation itself. Any remaining gas is refunded to the caller.

Therefore, it is generally more efficient to use revert when you want to signal an error condition and roll back the changes made by the contract, rather than using throw.

TAGS

If you enjoyed this article consider sharing it on social media or buying me a coffee ✌️

Buy Me A Coffee