Error/Exception handling in solidity

The error handling in solidity is one of the powerful mechanism to handle the runtime errors so that normal flow of the execution can be maintained.
Types of errors :
Runtime error : These errors occur during the execution of a smart contract and can be handled using mechanisms like require, assert, and custom error messages. For example, division by zero, out-of-bounds array access, or insufficient balance are runtime errors. Solidity provides ways to catch and handle these errors to prevent unintended behavior.
Compile Time error : These occur during the compilation of your Solidity code before deploying it to the Ethereum blockchain. These errors are typically related to syntax errors, undeclared variables, or other issues that prevent the code from being successfully compiled. Solidity compiler (solc) will report these errors, and you must fix them before deploying the contract. These errors are not "handled" in the traditional sense because they prevent the contract from being deployed in the first place.
Ways to handle the error in solidity :
Try-catch : The try statement allows you to define a block of code to be tested for errors while it is being executed. If any error occurs in the try block , catch block is used to handle those errors.
Example :
We use the try block to call the updateBalance function. If an error occurs in the updateBalance function, it is caught in the catch block, and you can handle the error accordingly.
Solidity
Copy
pragma solidity ^0.8.0; contract ErrorHandlingExample { uint256 public balance = 100; function withdraw(uint256 amount) public { try this.updateBalance(amount) { // Successful operation, continue } catch Error(string memory errorMessage) { // Handle the error here if anything breaks in try block } } function updateBalance(uint256 amount) internal { require(amount <= balance, "Insufficient balance"); balance -= amount; } }
Custom error Message :
We can create custom error message to give more context about the error. It is mainly helpful when providing more meaningful and informative feedback to users.
Example:
Let's consider a simple escrow contract where a buyer sends funds to the contract, and the seller can release the funds once the buyer confirms the delivery of goods. We'll throw the custom error to provide clear feedback to the participants.
Solidity
Copy
pragma solidity ^0.8.0; contract Escrow { address public buyer; address public seller; uint256 public escrowAmount; bool public goodsReceived; constructor(address _seller) { buyer = msg.sender; seller = _seller; escrowAmount = 0; goodsReceived = false; } function depositFunds() public payable { require(msg.sender == buyer, "Only the buyer can deposit funds."); require(msg.value > 0, "Deposit amount must be greater than zero."); escrowAmount += msg.value; } function confirmGoodsReceived() public { require(msg.sender == buyer, "Only the buyer can confirm goods received."); require(escrowAmount > 0, "No funds in escrow."); goodsReceived = true; } function releaseFunds() public { require(msg.sender == seller, "Only the seller can release funds."); require(goodsReceived, "Goods not yet received."); payable(seller).transfer(escrowAmount); escrowAmount = 0; } function refundBuyer() public { require(msg.sender == seller, "Only the seller can refund the buyer."); require(!goodsReceived, "Goods have already been received."); payable(buyer).transfer(escrowAmount); escrowAmount = 0; } }
revert : It is a specific mechanism in Solidity that allows you to revert the current transaction and provide an optional error message. It is the primary mechanism for handling exceptional conditions or errors in a smart contract.
Example :
Solidity
Copy
function withdraw(uint256 amount) public { if (amount > balance) { // Revert with an informative message revert("Insufficient funds for withdrawal."); } // Continue with the withdrawal logic }