[Solved!] Handling Error with TRY CATCH Block in Bash

LINUX
FUNDAMENTALS
A Complete Guide for Beginners Enroll Course Now

TRY…CATCH block is a fundamental construct for handling exceptions and errors gracefully in various programming languages. It allows you to create code that anticipates and responds to potential errors during execution. However, these errors can arise from missing files, invalid commands, network issues, or unexpected user input. This article will describe the scope of execution of TRY…CATCH in bash error handling. So, let’s start!

Is There a TRY CATCH Block in Bash?

There is no built-in TRY CATCH block in Bash, similar to what you might find in other programming languages like Python or Java. However, you can emulate similar behaviour using various Bash constructs and commands such as the ‘trap’ command, the ‘-x’ flag for tracing, and conditional logic etc.

How to Emulate TRY CATCH in Bash?

Bash offers several ways to emulate the functionality of the TRY CATCH block. These are:

1. Using the “trap” Command to Function as TRY CATCH

In Bash scripting, you can use the trap command to set up signal handlers that catch and handle errors or other events.

Here’s an example of using trap command to catch errors in a Bash script:

#!/bin/bash

# Function to handle errors
handle_error() {
    local line=$1
    echo "Error: Unable to delete file '$filename' at line $line"
    exit 1
}

# Set up error handling using trap
trap 'handle_error $LINENO' ERR

# File to delete
filename="example.txt"

# Attempt to delete the file
echo "Attempting to delete file: $filename"
rm "$filename"

# This line will only be executed if deletion is successful
echo "File $filename deleted successfully"
EXPLANATION

The given script attempts to delete a file, and if the deletion fails, it will print an error message. It sets up error handling using the trap command to call handle_error when an error occurs. The handle_error function manages errors, which displays an error message including the filename and the line where the error occurred, then exits with status 1.

Using the “trap” Command to Function as TRY CATCHAs you see from the image, the trap command triggers the handle_error function as soon as an error occurs and returns the customized message with the error line.

2. Using the “set” Command as TRY CATCH

The set command is used to modify shell options and variables in the Bash script. It can also be used to debug bash scripts, export shell script values, terminate programs in case of failure, and handle exceptions. You can utilize the set command to work as TRY CATCH  in the following ways:

A. “set” Command with “-x” flag to Catch the Error

By using the -x flag, you can enable debugging mode in Bash. This mode shows each command as it executes, including expansion and substitution. While the -x flag is useful for debugging scripts, it doesn’t specifically catch errors automatically. Rather, it helps in understanding the flow and finding the error line of the script with visible inspection.

Here’s an example of how to enable the -x flag in your script:

#!/bin/bash

# Enable debugging mode
set -x

# File to delete
filename="example.txt"

# Attempt to delete the file
echo "Attempting to delete file: $filename"
rm "$filename"

# This line will only be executed if deletion is successful
echo "File $filename deleted successfully"
EXPLANATION

In this bash script, set -x is used to turn on debugging mode. This helps in determining the execution steps. The script defines a variable filename as “example.txt” and tries to remove the file. The echo statements show the progress of the file deletion. The final echo statement indicates that the file has been deleted successfully.

Using the “set” Command with -x flag as TRY CATCHAs you see, the set -x enables the debugging mode, thus allowing each line to show in the terminal, before execution.

B. “set” Command with “-e” flag to Exit Upon Detecting Error

To exit upon detecting an error in Bash, use set -e at the beginning of your script. This setting makes the script exit immediately if any command exits with a non-zero status:

#!/bin/bash

# Enable debugging mode
set -e

# File to delete
filename="example.txt"

# Attempt to delete the file
echo "Attempting to delete file: $filename"
rm "$filename"

# This line will only be executed if deletion is successful
echo "File $filename deleted successfully"
EXPLANATION

This Bash script enables debugging mode using set -e, which exits immediately if any command fails. It then attempts to delete a file named “example.txt” using the rm command. If the deletion is successful, it prints a message confirming the deletion; otherwise, it exits without further execution.

“set” Command with “-e” flag to Exit Upon Detecting ErrorWhen running the script, there was no example.txt file in the current directory. Therefore, the script exits once it attempts to execute the rm "$filename" line and refrains from proceeding with the code further.

3. TRY CATCH with CASE Statements

Though try/catch blocks are not available in Linux, it is possible to imitate the behaviour of try/catch statements with the help of the CASE statement. For this, you first need to use helper scripts as shown below. Let’s name it as try_catch.sh:

# Define function to disable errexit
function try_block() {
    [[ $- = *e* ]]; SAVED_OPT_E=$?
    set +e
}

# Define function to exit with custom code
function raise_exception() {
    exit $1
}

# Define function to catch exceptions
function catch_exception() {
    export exception_code=$?
    (( $SAVED_OPT_E )) && set +e
    return $exception_code
}
EXPLANATION

This code defines three functions for implementing a try-catch mechanism in Bash. First, the try_block function disables the errexit option temporarily, allowing commands to continue executing even if errors occur. Then, the raise_exception function exits the script with a custom code provided as an argument. Finally, the catch_exception function catches exceptions by exporting the exception code, restoring the errexit option if it was previously enabled, and returning the exception code.

To identify and manage different types of error/exception more easily, incorporate the previous bash file try_script.sh into the following script:

# Include try_catch.sh as a library
source ./try_catch.sh

# Define custom exception types
export CUSTOM_ERR_BAD=100
export CUSTOM_ERR_WORSE=101
export CUSTOM_ERR_CRITICAL=102

try_block
(
    echo "Start of the try block"

    # When a command returns a non-zero, a custom exception is raised.
    ls || raise_exception $CUSTOM_ERR_BAD
    date || raise_exception $CUSTOM_ERR_WORSE
    run-command3 || raise_exception $CUSTOM_ERR_CRITICAL

    # This statement is not reached if there is any exception raised
    # inside the try block.
    echo "End of the try block"
)
catch_exception || {
    case $exception_code in
        $CUSTOM_ERR_BAD)
            echo "Error: This error is bad"
        ;;
        $CUSTOM_ERR_WORSE)
            echo "Error: This error is worse"
        ;;
        $CUSTOM_ERR_CRITICAL)
            echo "Error: This error is critical"
        ;;
        *)
            echo "Unknown error: $exception_code"
            raise_exception $exception_code    # Re-throw an unhandled exception
        ;;
    esac
}
EXPLANATION

The try-catch method in this script is derived from try_catch.sh. It defines the custom exception types and the try block where the commands are executed. When one of the commands fails (returning non-zero status) a custom exception is raised in the try block. The catch block takes care of these exceptions and displays the correct error messages based on the exception codes. If the exception is not handled, it is thrown again.

TRY CATCH with CASE StatementsHere, the first two commands execute themselves successfully and CUSTOM_ERR_BAD and  CUSTOM_ERR_WORSE exceptions weren’t raised. Thus only CUSTOM_ERR_CRITICAL were enabled due to the non-existent run-command3 command. Therefore, the terminal returns “Error: This error is critical” by matching the case statement.

Conclusion

To sum up, the try-catch function in bash improves error handling by enabling you to wrap code that is prone to errors in a TRY block and handle exceptions smoothly in the CATCH block. In this article, you have learned various ways to replicate the TRY CATCH block using the Bash script. However, if you have any questions or queries, feel free to comment below. Thank You!

People Also Ask

What is a try catch function in Bash?

There is no built-in “try-catch” construct in bash, like in some other programming languages. However, you can achieve similar behaviour using conditional statements and error-handling techniques. Typically, you use the trap command to check the commands and perform actions based on whether they succeed or fail.

When should we use try-catch?

In programming, you should use try-catch blocks when you anticipate that certain sections of your code may raise exceptions or errors that could disrupt the normal flow of execution. Try-catch blocks allow you to handle these exceptional conditions by providing alternative paths of execution or performing cleanup operations.

How do you catch an error and exit in Bash?

To catch and handle errors in Bash, use the trap command with the ERR signal to define a function that executes upon error. Within this function, perform cleanup tasks if necessary and exit the script with a non-zero status code using the exit command.

What is the best practice of try catch?

To implement the TRY CATCH in Bash scripts, you should define the  TRY CATCH block as a function. The code should be concise and clear. In the TRY CATCH block, utilize custom exception types to deliver meaningful error messages. Ensure that, the block offers informative error reporting and encompasses resource cleanup within the catch block. Thoroughly test the TRY CATCH block. Use documentation for clarity and follow the standard error-handling conventions.

Related Articles


<< Go Back to Bash Error Handling | Bash Error Handling and Debugging | Bash Scripting Tutorial

Rate this post
Mohammad Shah Miran

Hey, I'm Mohammad Shah Miran, previously worked as a VBA and Excel Content Developer at SOFTEKO, and for now working as a Linux Content Developer Executive in LinuxSimply Project. I completed my graduation from Bangladesh University of Engineering and Technology (BUET). As a part of my job, i communicate with Linux operating system, without letting the GUI to intervene and try to pass it to our audience.

Leave a Comment