What Is Exception Handling: Types and Best Practices

Tahneet Kanwal

Posted On: January 23, 2025

view count9853 Views

Read time17 Min Read

Exceptions are events that occur when the program is running to signal the programmer that something unexpected has happened.

They can occur for various reasons, such as invalid code logic, external factors like device failures, or runtime issues like insufficient memory. Handling exceptions becomes important because it may interrupt the normal flow of the program.

Handling exceptions helps ensure that the program works as expected and also recovers from unexpected conditions by providing meaningful feedback on what went wrong. If these events are not handled properly, they can lead to the breakage or unexpected behavior of the code.

What Is Exception Handling?

Exception handling is a technique in programming to handle runtime errors, allowing the program to execute and recover when unexpected situations occur. Instead of showing errors and terminating a program, exception handling provides a structure to deal with errors and manage them appropriately. With a special block of code called an exception handler, you can handle errors effectively.

In many programming languages, exception handling is added using try, catch blocks where:

  • try: This block contains code that might cause an exception.
  • catch: This block handles the exception when it occurs.

This exception handler helps you handle various unexpected issues without terminating the program.

Here are the benefits of using exception handling:

  • Ensures Program Continuity: It allows the program to recover from errors and continue running, avoiding issues like data loss.
  • Enhances Program Robustness: It helps programs anticipate and recover from errors, making them more reliable in handling unexpected situations.
  • Improves Code Readability and Maintainability: It provides detailed error messages that describe problems accurately, simplifying future modifications and debugging tasks.
  • Supports Accurate Error Reporting: It provides detailed and precise error reporting that helps developers identify and fix issues efficiently during debugging and troubleshooting.
  • Improves Program Security: It helps maintain critical data protected from being displayed or logged in error messages.
  • Provides a Better User Experience: It allows for the implementation of recovery mechanisms like retries or fallback options.
  • Improves Scalability and Performance: It reduces system load and enhances overall performance, contributing to scalability.

Now that you understand exception handling and its benefits, let’s explore the different types of exception handling in popular programming languages like Java and Python.

Exception Handling In Java

Exception handling in Java can be handled using ClassNotFoundException, IOException, SQLException, and others to ensure the program keeps running.

When an exception occurs, the JVM creates an exception object containing details like the name and description of the issue and the program’s state when the exception happened.

If an appropriate handler is found, the exception is passed to it for processing. If no handler exists, the JVM’s default exception handler prints the exception details, including its type and location, and terminates the program abnormally. This process helps prevent unexpected crashes and provides meaningful error messages.

Java organizes exception classes in a hierarchy structure, defining relationships between general and more specific types of exceptions.

Java Exception Hierarchy:

In Java, all exceptions and errors inherit from the Throwable class, which is the root of the exception hierarchy. This hierarchy is divided into two main branches.

  • Exception: This branch includes conditions that programs can handle, such as IOException, which occurs when there is an issue with input or output operations.
  • Error: This branch represents critical issues related to the Java runtime environment, like OutOfMemoryError, which occurs when the JVM runs out of memory to allocate objects.

Below is the hierarchy of Java’s exception classes:

java

Types of Exceptions in Java

In Java, exceptions are broadly categorized into two types:

  • Built-in Exception: Java libraries that provide built-in exceptions that help identify specific error situations. These predefined exceptions clearly indicate what went wrong during program execution.
  • Checked Exception: These are compile-time exceptions that the compiler verifies during compilation. The programmer must explicitly handle these exceptions using try-catch blocks or declare them using the throws keyword.
    • FileNotFoundException: This occurs when trying to access a file that doesn’t exist.
    • IOException: This occurs when input/output operations fail.
    • SQLException: This occurs when database operations fail.
    • ClassNotFoundException: This occurs when trying to load a class that doesn’t exist.
  • Unchecked Exception: Unchecked exceptions, or runtime exceptions, are not checked at compile-time. These exceptions result from programming errors, such as logical errors or incorrect calculations in the code.
  • Common exceptions include:

    • ArithmeticException: When performing invalid arithmetic operations (like division by zero).
    • NullPointerException: This occurs when trying to attempt to use a null reference.
    • ArrayIndexOutOfBoundsException: This occurs when trying to access an array element outside its bounds.
    • IllegalArgumentException: This occurs when a method receives an invalid argument.
    • NumberFormatException: This occurs when trying to convert an invalid string to a number.
  • User-defined Exception: In Java, built-in exceptions handle general scenarios, but user-defined exceptions are helpful when specific conditions require custom error handling. These exceptions can be created by extending the Exception class and throwing them with the throw keyword.

Below is an example of a custom exception for invalid API responses during testing:

The program consists of two classes: ApiTesting and InvalidApiResponseException. The ApiTesting class checks the status code of an API response. If the code is not 200, it throws a custom exception, InvalidApiResponseException, which extends the Exception class. This exception stores the invalid status code and provides a custom error message.

Exception Handling Keywords in Java

In Java, there are five important keywords specifically used for handling exceptions in a program.

Keyword Description
try Defines a block of code where exceptions might occur. It must be followed by either catch or finally.
catch Handles exceptions that occur in the preceding try block. It cannot exist without a try block.
finally Contains code that executes regardless of whether an exception occurs or is handled.
throw Explicitly throws an exception.
throws Declares potential exceptions that a method might throw. Used in method declarations.

Example of Exception Handling in Java

Here’s an example of Java exception handling, where a FileNotFoundException is handled using a try-catch statement:

Output:

In the above example, a FileNotFoundException is raised when trying to open a file that doesn’t exist. The exception is caught by the catch block, and the error message is printed. After handling the exception, the program continues and prints “Program continues…”.

Now that we have covered how to handle exceptions in Java, let’s explore how to handle exceptions in Python.

Exception Handling In Python

Exception handling in Python is similar to handling exceptions in Java. The core concept of exceptions remains the same. It allows you to handle unexpected or unwanted errors gracefully, preventing the program from crashing or terminating unexpectedly.

When an unexpected condition occurs, Python creates an exception object that consists of information about the type, message, and location in the program. The programmer must add an exception handler in the code; if the handler is found, the exception is processed; otherwise, Python’s default exception handler prints the details of the error and terminates the program.

Python organizes exceptions with a base class called BaseException, from which other exception classes inherit. This hierarchy allows developers to handle exceptions more from generic or specific as needed.

The BaseException class is at the top of Python’s exception hierarchy and includes common methods like __str__ and __repr__ that all exceptions can use. However, it is not recommended to use BaseException directly in code because it is too general and can catch all exceptions, including critical ones like system exit or keyboard interruption. Instead, more specific exception classes that are subclasses of BaseException should be used.

Python provides many built-in exception classes, and custom exception classes can also be created as needed.

Python Exception Hierarchy:

Here’s an overview of the hierarchy in Python exception classes:

python

Types of Exceptions in Python

Here are some common exceptions in Python with the errors that cause them:

  • Syntax Errors: These occur during parsing errors when Python can’t understand your code due to violations of the language rules or syntax errors. These errors prevent the code from being executed.
  • Common exceptions include:

    • SyntaxError: Raised when the parser encounters invalid Python syntax (e.g., missing parentheses, invalid function declaration).
    • IndentationError: It occurs when code blocks are not properly indented in Python’s required format.
    • TabError: Raised when mixing tabs and spaces incorrectly for indentation in the same code block.
  • Built-in Exceptions: These are standard exceptions that occur during program execution due to invalid operations or logical errors. These can be handled using try-except blocks.
  • Common exceptions include:

    • AssertionError: Occurs when an assert statement fails.
    • AttributeError: Occurs when an attribute reference or assignment fails.
    • ImportError: Occurs when module imports fail.
    • IndexError: Occurs when trying to access a list/sequence index that’s out of range.
    • NameError: Occurs when code tries to use a variable or name that hasn’t been defined.
    • ValueError: Occurs when a function receives the right type of argument but with an inappropriate value.
    • ZeroDivisionError: Occurs when dividing by zero.
  • System Errors: These represent the critical issues involving the Python interpreter or system resources. They can technically be caught using a try-catch block, but it’s not recommended. They indicate the issues that require system-level debugging or resource management rather than being handled programmatically.
  • Common exceptions include:

    • MemoryError: Occurs when an operation runs out of memory.
    • RecursionError: Occurs when maximum recursion depth is exceeded (typically due to infinite recursion).
    • SystemError: Indicates an internal system error in the Python interpreter.
    • OSError: Base class for system-related errors (like IOError, FileNotFoundError).
    • GeneratorExit: Occurs when a generator/coroutine is closed.
    • SystemExit: Occurs when sys.exit() is called to terminate the program.
  • User-Defined Exceptions: These are custom exceptions that programmers can create by inheriting from the Exception class. They are useful for handling application-specific error conditions and improving code readability by providing meaningful error messages.

Below is an example of a custom exception for handling multiple exceptions in Python:

All of these exceptions can be caught and handled using try-except blocks, and you can specify multiple exception handlers:

Exception Handling Keywords in Python

Python provides several keywords for exception handling to manage errors or unexpected situations that occur during the execution of a program.

Keyword Description
try It encloses code where exceptions might occur and monitors potential error-producing areas.
except It catches and handles exceptions from the try block. It can also handle multiple exception types and store the error in a variable.
else It runs code only when no exception occurs in the try block.
finally It runs even after return statements and executes cleanup code regardless of whether an exception occurred.
raise It can create custom exceptions or re-raise caught exceptions
assert It is used to validate conditions and raises AssertionError if False.

Example of Exception Handling in Python

Here’s an example of how to handle a FileNotFoundError in Python. This occurs when attempting to open a file that doesn’t exist. The exception is raised and can be caught using a try-except block.

Output:

In the above example, if the file does not exist, Python raises a FileNotFoundError. This error is caught by the except block, and an error message is printed. After handling the exception, the program continues its execution, as indicated by the message “Program continues…”.

Catching and Raising Exceptions in Python

Catching and raising exceptions in Python involves using a try-except block to handle errors and the raise keyword to generate exceptions manually.

Let’s understand catching exceptions and raising exceptions in detail.

Catching Exceptions: To catch exceptions, Python uses the try, except, and finally blocks. The code that could cause an exception is placed in the try block, while the except block handles the error. The finally block always executes, whether an exception occurs or not, to clean up the actions.

Output:

Raising Exceptions: In Python, the keyword raise is used to raise an exception manually. This is useful when you want to enforce specific error handling or trigger custom exceptions for application-specific scenarios.

Output:

Catching and raising exceptions in Python helps control error management and ensures that the program continues running smoothly. Proper exception handling in Java, Python, or any language helps manage unexpected scenarios and prevent crashes.

Exception handling is crucial for writing robust code. Java and Python are programming languages that also enable the writing of test scripts. Both languages offer built-in exceptions, which make it easier for developers and QA engineers to detect, catch, and resolve errors.

Having exception handling from a testing perspective provides more confidence in the quality and reliability of the application as well.

When it comes to testing, test automation is performed on various combinations of browsers and operating systems, making the test code behave differently because of varying browsers and browser versions. The test might throw an exception because of some attributes that are browser-specific and might not be present on other browsers on which the test is being performed. For example, you might encounter NoSuchAttributeException because of property names when using test automation frameworks like Selenium. You can learn more about it through this blog on common Selenium exceptions.

Handling exceptions in Selenium differs based on the programming language being used.

If you are using Python, the exceptions are handled using the try…except block, where the exception classes are imported from the selenium.common.exceptions package. Similarly, in Java, the exceptions are handled using the try-catch statement.

Similar to Selenium exceptions, understanding exception handling in Cypress is equally important when working with the Cypress framework.

Handling exceptions effectively in Selenium and Cypress ensures that your test scripts remain robust and adaptable. However, the true power of exception handling can be realized when combined with a reliable testing platform like LambdaTest.

AI-based test execution and orchestration platforms like LambdaTest offer manual and automated testing across 3000+ browsers and OS combinations. By running your Selenium and Cypress tests across multiple environments, LambdaTest helps you identify browser-specific exceptions that might go undetected while testing at scale.

Best Practices for Exception Handling

Exception handling is essential for managing errors and ensuring smooth execution in both Java and Python. Below are the best practices to be followed:

  • Catch Specific Exceptions: Always catch specific exceptions rather than catching broad ones. This helps in providing more precise error handling and makes the code easier to maintain and debug. Specific exception classes provide more context about the error, allowing developers to handle it appropriately.
  • Keep Exception Handling Simple: It’s better to keep exception handling simple and focused on the specific error it is intended to handle, never add complex logic in exception handling. Overcomplicated handling makes the code harder to understand and maintain.
  • Log Exceptions: You need to log exceptions or error messages for troubleshooting. Logging errors helps to diagnose issues, especially in production environments, and provides a trace to follow when debugging problems.
  • Throw Exceptions Appropriately: Throw exceptions only when necessary. Avoid excessive use of checked exceptions. Use them for exceptional conditions that the caller is expected to handle.
  • Use Custom Exceptions: Create custom exceptions to represent specific error conditions in your application. This will help provide meaningful error messages and make your code more self-documenting.
  • Do Not Suppress Exceptions: Never catch exceptions without doing anything meaningful with them. Suppressing exceptions can make it harder to identify and solve problems.
  • Use Meaningful Error Messages: Provide clear and concise error messages. The message should explain what went wrong and potentially guide the user toward fixing the issue.
  • Handle All Possible Errors: Always handle all possible exceptions your code might throw. This helps prevent unexpected crashes and ensures the program runs smoothly.
  • Conclusion

    In conclusion, exception handling is crucial in both Java and Python. It helps programs handle unexpected errors that may occur during execution. Instead of causing the program to crash, the errors can be caught and managed properly. This allows the program to continue running or exit in a controlled way. Proper exception handling increases a program’s durability and dependability.

    It helps ensure that the program remains functional under various conditions. This makes it easier for developers to maintain and debug the code because they can quickly identify and fix problems. It also makes the program easier to maintain, as developers can quickly understand and fix any issues.

    Frequently Asked Questions (FAQs)

    Why does an exception occur?

    An exception occurs when the program encounters an error that disrupts its normal flow, such as accessing a non-existing file or trying to divide by zero.

    Define Java exception chaining.

    Java exception chaining happens when one exception is thrown while handling another. The second exception can be linked to the first using the from keyword, preserving the stack trace.

    What happens if an exception is not caught in a Python program?

    If an exception is not caught, the Python program will stop executing, and the exception will be printed with a traceback showing where the error occurred.

    Why is the finally block necessary when handling exceptions?

    The finally block ensures that certain code, like closing files or releasing resources, runs no matter what, even if an exception is thrown.

    How does the program behave if the main method throws an exception?

    If the main method throws an exception, the program will terminate immediately, and the exception will be displayed in the console. The exception prevents the program from continuing unless it is caught and handled within the code.

    How can you suppress exceptions in Python?

    You can suppress exceptions in Python using a try-except block without writing any handling code, though it is not recommended.

    What happens to the exception object after exception handling is complete?

    After exception handling is complete, the exception object is discarded unless explicitly logged or re-raised, and the program continues to run normally.

    Citations

    1. Exception Handling in Python: https://docs.python.org/3/tutorial/errors.html
    2. Exception Handling in Java: https://docs.oracle.com/javase/tutorial/essential/exceptions/
    3. A complete hierarchy of built-in exceptions in Python:
    4. https://docs.python.org/3/library/exceptions.html#exception-hierarchy

Author Profile Author Profile Author Profile

Author’s Profile

Tahneet Kanwal

Tahneet Kanwal is a software engineer with a passion for frontend development and a keen eye for user experience. With a strong foundation in web technologies, she brings a practical perspective to her writing. As a technical content writer at LambdaTest, Tahneet combines her engineering expertise with her communication skills to craft engaging, SEO-friendly articles. Her work spans various topics in web development, software testing, and emerging tech trends, keeping readers informed and inspired.

Blogs: 29



linkedintwitter

Test Your Web Or Mobile Apps On 3000+ Browsers

Signup for free