Solidity Error Handling
Written by Shray Jain
Reviewed by Brady Werkheiser
How does error handling work in Solidity?
Solidity uses state-reverting exceptions to handle errors, and such an exception will undo all changes made to the state in the current call and simultaneously flag an error to the caller.
Solidity, an object-oriented programming language to implement smart contracts on blockchains such as Ethereum, has numerous functions to address underlying issues that can occur at compile time or runtime. Even though syntax error checks happen at compile time, runtime errors are difficult to catch and mainly happen during the contract execution process. Some runtime error examples include a divide-by-zero type error, array-out-of-index error, and so on.
In effect, error handling in Solidity ensures atomicity as a property. When a smart contract call terminates with an error, all the state changes (i.e., alterations made to variables, balances, etc.) are reverted, all the way up the chain of contract calls.
It is important to note that developers can directly interact with other contracts by declaring an interface. On the Ethereum blockchain, transactions are atomic, implying that transactions are either fully complete or have no effect on state and are reverted entirely.
What are the three main Solidity error handling functions?
Error handling in Solidity is managed in principle by three special functions: assert, require, and revert. Until version 0.4.10, a single throw statement was available in Solidity.
Solidity has been designed to target the Ethereum Virtual Machine (EVM) and is influenced by C++, Javascript, and Python. Using Solidity, developers can create contracts for uses such as voting, crowdfunding, multi-signature wallets, and even blind auctions.
In practice, this means that a developer had to write several test functions in order to check underlying values and throw errors, which is not optimized for gas. In the release of Solidity version 0.4.10, new error handling constructs, asset, require, and revert, were introduced and the throw was made obsolete.
What is the require function?
The require function is used to verify inputs and conditions before execution. For instance, if the condition is false, then the require function immediately stops execution. In other words, require acts as a gate check modifier, preventing logic from accessing further execution of function and thereby producing an error. Require is ideal for logic flow gating and validating user inputs on functions.
Require statements declare prerequisites for running the function, which should be satisfied prior to code execution. The require function accepts a single argument and after evaluation, require returns a boolean value of true or false. In the event that the execution is terminated due to a false condition, the unused gas is returned to the caller and the state is reversed to the original state. Customer string messages can also be added.
Here is an example of a require statement in Solidity:
Require Statement Use Cases
For pragmatic reasons, developers could use require for the following scenarios:
Validating responses from an external contract
Verify state conditions before final execution
Authenticate user inputs
What is the revert statement?
Revert does not evaluate any condition and does not depend on any state or statement. The revert statement is similar to the require statement in that the revert function can handle the same error types as the require function, but it is more appropriate for complex logic gates.
If a revert statement is called, the unused gas is returned and the state reverts to its original state. The ability to add a custom message is the same as the require function.
Here is an example of a revert statement in Solidity:
revert("Something funky has occured");
What is the assert function?
Assert is a function that is used to check for code that should never be false, and plays an important role in preventing impossible scenarios. If the assert function returns a boolean value of true, then a terminal bug will be displayed and the programs will not execute.
In contrast to the require and revert functions, assert does not return any unused gas and instead, the assert function will consume the gas supply before proceeding to reverse the program to its original state. Interestingly, prior to the Byzantium fork, both the require and assert functions behaved in an identical manner, however, compiled to distinct opcodes.
Assert Type Exceptions
A value is modulo or divided by zero
A zero-initialized variable of a function is called
A negative or large value is converted to an enum
Accessing an array within an index that is negative or larger than expected
Assert statement example:
assert(num >= 0);
Assert Statement Use Cases
In theory, assert should be used less frequently compared to the require function. Developers should consider using the assert function for the following use cases:
Validating the contract state after making changes
Avoiding conditions which should never be possible
Checking for overflow and underflow parameters
Examining invariants
Require vs. Revert vs. Assert
Here is a summary that provides a succinct description of all all three Solidity error handling functions: require, revert, and assert.
Require
Used at the beginning of a function
Validates against illegal input
Verifies state conditions prior to execution
Refunds leftover gas
Revert
Identical to require
Useful for more complex logic flow gates (i.e., complicated if-then blocks)
Refunds leftover gas
Assert
Used at the end of a function
Validates something that is impossible
Critical for static code analysis tools
Does not refund leftover gas
How to Learn More About Require and Solidity Error Handling
Developers interested in learning more about Solidity error handling should sign up for Alchemy University's free Solidity developer crash course. This FREE, 7-week bootcamp helps web2 developers and brand new coders learn how to write Solidity smart contracts. If developers are new to development in general, Alchemy University's 3-week JavaScript crash course is a great prerequisite before starting an Ethereum bootcamp.
Related overviews
What it is, How it Works, and How to Get Started
Explore the Best Free and Paid Courses for Learning Solidity Development
Your Guide to Getting Started With Solidity Arrays—Functions, Declaring, and Troubleshooting