Week 10: Mastering Error Handling

Learn how to deal with errors and exceptions in Python to make your programs more robust.

Explore Chapter 10

Chapter 10: Dealing with Errors and Exceptions

Types of Errors in Python.

Errors are inevitable in programming. Understanding the different types of errors is crucial for writing code that can gracefully handle unexpected situations.

Syntax Errors

Syntax errors occur when you violate the rules of the Python language. They are usually caught by the interpreter before the program even starts running.

# Example of a syntax error: missing colon
# if x > 5
#     print("Hello")

# Example of a syntax error: mismatched parentheses
# print("Hello"

Syntax errors are typically easy to fix once you identify them, as the interpreter provides an error message indicating the line where the error occurred.

Runtime Errors (Exceptions)

Runtime errors, also known as exceptions, occur during the execution of the program. They happen when the syntax is correct, but the program encounters an unexpected condition that it cannot handle.

Some common types of exceptions include:

  • `TypeError`: Occurs when an operation or function is applied to an object of an inappropriate type.
    # Example: Trying to add a number to a string
    # 10 + "hello"
  • `ValueError`: Occurs when a function receives an argument of the correct type but an inappropriate value.
    # Example: Trying to convert an invalid string to an integer
    # int("abc")
  • `IndexError`: Occurs when you try to access an index in a sequence (like a list or tuple) that is out of range.
    # Example: Accessing an invalid index in a list
    # my_list = [1, 2, 3]
    # print(my_list[5])
  • `KeyError`: Occurs when you try to access a key that doesn't exist in a dictionary.
    # Example: Accessing an invalid key in a dictionary
    # my_dict = {"a": 1, "b": 2}
    # print(my_dict["c"])
  • `FileNotFoundError`: Occurs when you try to open a file that doesn't exist.
    # Example: Trying to open a file that doesn't exist
    # open("nonexistent_file.txt", "r")
  • And many others!

Exception Handling using `try`, `except`, `finally`.

Python provides a mechanism to handle exceptions using the `try`, `except`, and `finally` statements. This allows you to write code that can gracefully recover from or at least manage runtime errors.

`try` and `except` Blocks

The `try` block contains the code that might raise an exception. The `except` block specifies how to handle a specific exception if it occurs within the `try` block.

try:
    # Code that might raise an exception
    # ...
except ExceptionType1:
    # Code to handle ExceptionType1
    # ...
except ExceptionType2:
    # Code to handle ExceptionType2
    # ...
except:
    # Code to handle any other exception (optional, use with caution)
    # ...

When an exception occurs within the `try` block, Python looks for a matching `except` block to handle it. If a matching `except` block is found, the code within that block is executed. If no matching `except` block is found, the exception propagates up the call stack, and if it's not handled anywhere, the program will terminate.

Example

try:
    num1 = int(input("Enter the first number: "))
    num2 = int(input("Enter the second number: "))
    result = num1 / num2
    print("Result:", result)
except ValueError:
    print("Invalid input. Please enter numbers only.")
except ZeroDivisionError:
    print("Cannot divide by zero.")

`finally` Block

The `finally` block is optional and is used to specify code that should be executed no matter whether an exception occurred or not. It is often used for cleanup operations (e.g., closing files, releasing resources).

try:
    file = open("my_file.txt", "r")
    # Code that might raise an IOError
    # ...
except IOError:
    print("An error occurred while reading the file.")
finally:
    file.close()  # Ensure the file is closed, even if an error occurred

Raising Exceptions.

In addition to handling exceptions, you can also explicitly raise exceptions in your code using the `raise` statement. This is useful when you want to signal that an error condition has occurred.

`raise` Statement

raise ExceptionType("Error message")

You can raise built-in exceptions or create your own custom exception classes (we won't cover custom exception classes in this introductory course).

Example

def get_age(age):
    if age < 0:
        raise ValueError("Age cannot be negative.")
    return age

try:
    user_age = int(input("Enter your age: "))
    age = get_age(user_age)
    print("Age:", age)
except ValueError as e:
    print("Error:", e)

In this example, the `get_age` function raises a `ValueError` if the provided age is negative. The `try-except` block handles this exception and prints an appropriate error message.

Syllabus