Error handling with throw and revert: differences and gas usage
Published
Table of contents
In this article we're going to see different ways to handle errors in Solidity using throw
, revert
and also require
.
throw
Exceptions with 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.
revert
Errors with 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