Rise In Logo

Build on Scroll

In Solidity, error handling is crucial for controlling contract execution and managing state under failure conditions. Effective error handling prevents contracts from executing unintended actions and ensures that users receive meaningful feedback when operations fail.

Let’s start with a quick introduction on error handling.

Introduction to Error Handling

Error handling in Solidity involves several key mechanisms:

1. Revert: Reverts the transaction and undoes all changes made to the state, while providing an error message.

2. Require: A shorthand for reverting the transaction if a condition is not met.

3. Assert: Used to test for internal errors and invariants; reverts the transaction if a condition evaluates to false.

4. Try/Catch: Handles exceptions in external function calls and contract creations.


The revert statement stops execution and reverts any changes made to the state during the transaction. It also allows you to provide an error message.

function buyItem(uint itemId) public payable {

    if (msg.value < items\[itemId\].price) {

        revert("Payment is not enough.");


    // Continue with purchase logic



You have already seen require in the Modifiers lesson. For a quick reminder, let’s take another look at it if you need a refresher.

Require is used to assert conditions before executing an operation. If the condition is false, the operation is reverted and a specified error message is returned. It is most commonly used to validate inputs and conditions.

function withdraw(uint amount) public {

    require(amount <= balances\[msg.sender\], "Insufficient balance.");

    balances\[msg.sender\] -= amount;




Assert is used for checking invariants and internal conditions that should never fail if the contract functions correctly. It consumes all gas when an assertion fails, signaling a critical error.

function divide(uint a, uint b) public pure returns (uint) {

    assert(b != 0);  // Prevent division by zero

    return a / b;



Introduced in Solidity 0.6, `try/catch` blocks allow handling exceptions from external contract calls or contract creations using `new`.

interface IExternalContract {

    function someFunction(uint x) external returns (bool);


contract Caller {

    IExternalContract externalContract;

    constructor(address \_contractAddress) {

        externalContract = IExternalContract(\_contractAddress);


    function callExternalFunction(uint x) public returns (bool) {

        try externalContract.someFunction(x) {

            return true;

        } catch {

            // Handle the case where the call fails

            return false;




Do not worry if you have not understood the interface. You will see the interface in the next lesson.

Before finalizing this lesson, let’s have a look at the best practices.

Best Practices in Error Handling

  • Use require for input validation or conditions that must be met for the function to proceed.
  • Use assert to check for conditions that indicate a bug in the contract code.
  • Handle potential failures in external calls using try/catch.
  • Provide clear and informative error messages to help with debugging and user interaction.

In summary, effective error handling is crucial for developing robust and secure smart contracts. It ensures that contracts only perform intended actions and provide useful feedback, thereby enhancing the security and reliability of your applications.




You need to enroll in the course to be able to comment!

Stay in the know

Never miss updates on new programs and opportunities.

Rise In Logo

Rise together in web3!