Exception Handling

Master exception handling in LLM and AI development. Learn to gracefully manage runtime errors and unexpected events in your machine learning projects. Explore best practices for robust code.

Exception Handling

This document provides a comprehensive guide to exception handling in programming. Exception handling is a fundamental mechanism for dealing with runtime errors or unexpected events that disrupt the normal flow of a program.

7.1 Understanding Exception Handling

Exception handling allows you to gracefully manage errors that occur during program execution. Instead of crashing the program, you can "catch" these exceptions and execute alternative code paths to handle the situation, log the error, or inform the user.

The core concepts involve:

  • Raising an Exception: When an error occurs, the program "raises" an exception object that describes the error.

  • Catching an Exception: Other parts of the program can "catch" these raised exceptions and respond to them.

  • try...except Blocks: The primary way to implement exception handling is using try and except blocks. Code that might cause an exception is placed within the try block. If an exception occurs, the corresponding except block is executed.

try:
    # Code that might raise an exception
    result = 10 / 0
except ZeroDivisionError:
    # Code to handle the ZeroDivisionError
    print("Error: Cannot divide by zero!")

7.2 Catching Multiple Exceptions

A single try block can be followed by multiple except blocks to handle different types of exceptions. The except blocks are checked in order, and the first one that matches the raised exception will be executed.

try:
    num = int(input("Enter a number: "))
    result = 100 / num
    print(f"The result is: {result}")
except ZeroDivisionError:
    print("Error: You cannot divide by zero.")
except ValueError:
    print("Error: Invalid input. Please enter an integer.")
except Exception as e: # Catch any other unexpected exceptions
    print(f"An unexpected error occurred: {e}")

7.3 Raising an Exception

You can explicitly raise an exception using the raise keyword. This is useful for signaling error conditions in your own code when a predefined exception type doesn't perfectly fit or when you want to enforce specific error handling.

def validate_age(age):
    if age < 0:
        raise ValueError("Age cannot be negative.")
    elif age > 120:
        raise ValueError("Age seems unrealistic. Please enter a valid age.")
    else:
        print("Age is valid.")

try:
    validate_age(-5)
except ValueError as ve:
    print(f"Validation Error: {ve}")

7.4 The finally Keyword

The finally block contains code that will be executed regardless of whether an exception occurred or not. This is often used for cleanup operations, such as closing files or releasing resources, ensuring they are always handled.

file = None
try:
    file = open("my_file.txt", "r")
    content = file.read()
    print(content)
    # Simulate an error
    result = 10 / 0
except FileNotFoundError:
    print("Error: The file was not found.")
except ZeroDivisionError:
    print("Error: A division by zero occurred.")
finally:
    if file:
        file.close()
        print("File has been closed.")
    print("Execution of try-except-finally block finished.")

7.5 Built-in Exceptions

Most programming languages provide a rich set of built-in exceptions that cover common error scenarios. Familiarizing yourself with these can help you write more robust code. Some common examples include:

  • ArithmeticError: Base class for arithmetic-related errors.

    • ZeroDivisionError: Division or modulo by zero.

    • OverflowError: Arithmetic operation result is too large to be represented.

  • LookupError: Base class for errors when a key or index used on a mapping or sequence is invalid.

    • IndexError: Sequence index is out of range.

    • KeyError: Dictionary key not found.

  • NameError: Name not found.

  • TypeError: Operation or function applied to an object of inappropriate type.

  • ValueError: Operation or function receives an argument that has the right type but an inappropriate value.

  • FileNotFoundError: File or directory not found.

  • IOError: Input/output operation failed.

  • Exception: The base class for all non-exit exceptions. Catching Exception is a broad way to handle most errors.