Custom error handling enables Solidity developers to efficiently handle reverts and failed transactions including logging parameters.
Let’s first take a look at an example from the Solidity Snippets Github repo:
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
error MyCustomError(uint var1, uint var2);
contract CustomErrors {
function test() pure public {
if (1 > 0) revert MyCustomError(1,2);
}
}
Note that the Solidity compiler version must be greater than 0.8.4 to use custom errors.
Customer errors are supported by Etherscan and most other block explorers and debugging tools. Note that error handling is still Solidities biggest weakness in my opinion and often there isn’t much to go on when trying to debug transactions
Transactions on the Ethereum virtual machine are atomic. When a transaction terminates with an error, all state changes made within that call are rolled back, effectively undoing any alterations made to variables, balances, and other data.
Solidity ensures that this atomicity property is maintained across the entire chain of contract calls. If a contract calls another contract, and that contract fails, then all state changes made in both contracts are rolled back, ensuring that the system remains consistent and free from errors.
Try Catch Statements
If you want to handle an error without creating an fatal exception enclose the code in a try catch statement
function tryCatch(uint _x) public {
try myFunc(_x) returns (uint _y) {
console.log(_y);
} catch {
console.log('oh no :(');
}
}
Revert, Require, Assert
Revert is used to revert the entire transaction when a condition is not met. It is typically used to handle errors in user input or external contract calls. When a revert statement is executed, all changes to the state are reverted. The message passed to the revert statement is included in the transaction receipt and can be used to provide feedback to the user.
revert("The world has ended");
Require is similar to revert, but it is used to check a conditional statement. When a require statement fails, the transaction is reverted.
require(1 > 0, "This should never revert");
Assert is used to check a conditional statement for errors and the transaction is reverted. Assert should be used sparingly and only in situations where an internal error should never occur.
assert(1 > 0);
I hope this article on custom error handling in Solidity has proved of interest and that you don’t see too many of these revert messages pop up in the future. Happy debugging