What is Error Handling in Python?

Error handling in Python ensures that your program continues running smoothly even when unexpected errors occur. Using tools like try, except, and finally, you can catch and handle errors gracefully, preventing crashes.

Common Types of Errors in Python

Error TypeDescriptionExample
SyntaxErrorRaised when there’s a syntax error in the codeif True print("Hello")
TypeErrorRaised when an operation is performed on an invalid type"1" + 1
ValueErrorRaised when a function receives an argument of the correct type but an invalid valueint("abc")
IndexErrorRaised when accessing an invalid index in a list[1, 2, 3][3]
KeyErrorRaised when accessing a non-existent dictionary key{"name": "Alice"}["age"]
ZeroDivisionErrorRaised when dividing by zero10 / 0

Basic Error Handling: try-except Block

The try block lets you test code for errors, and the except block handles the error if it occurs.

Syntax:

try:
    # Code that may cause an exception
except <ExceptionType>:
    # Code to handle the exception

Example: Handling Division by Zero

try:
    result = 10 / 0
except ZeroDivisionError:
    print("Error: Division by zero is not allowed.")

Catching Multiple Exceptions

You can handle different types of exceptions using multiple except blocks.

Example:

try:
    value = int(input("Enter a number: "))
    result = 10 / value
except ValueError:
    print("Invalid input! Please enter a valid number.")
except ZeroDivisionError:
    print("Error: Cannot divide by zero.")

Using the else Block in Python

The else block executes if no exceptions are raised in the try block.

Example:

try:
    result = 10 / 2
except ZeroDivisionError:
    print("Division by zero is not allowed.")
else:
    print(f"The result is {result}.")

The finally Block in Python

The finally block always executes, regardless of whether an exception was raised.

Example:

try:
    file = open("example.txt", "r")
    content = file.read()
except FileNotFoundError:
    print("File not found!")
finally:
    print("Cleaning up resources...")
    file.close()

Raising Exceptions

Use the raise statement to trigger an exception manually.

Example:

def validate_age(age):
    if age < 0:
        raise ValueError("Age cannot be negative.")
    print(f"Age is {age}.")

try:
    validate_age(-1)
except ValueError as e:
    print(e)

Custom Exceptions in Python

Create your own exceptions by subclassing the Exception class.

Example:

class CustomError(Exception):
    pass

try:
    raise CustomError("This is a custom error!")
except CustomError as e:
    print(e)

Best Practices for Error Handling in Python

Be Specific with Exceptions:

  • Avoid using a generic except unless necessary.
 
try:
    result = 10 / 0
except ZeroDivisionError:
    print("Cannot divide by zero.")
  • Use finally for Cleanup:

    • Ensure resources like files or network connections are closed properly.
  • Log Errors:

    • Use logging instead of print for tracking issues.
import logging
logging.basicConfig(level=logging.ERROR)
try:
    result = 10 / 0
except ZeroDivisionError as e:
    logging.error("Error occurred: %s", e)
  • Avoid Silent Failures:

    • Always log or notify users when an error occurs.
  • Use Assertions for Debugging:

    • Validate assumptions in the code using assert.
assert 2 + 2 == 4, "Math error!"

Common Use Cases for Error Handling

1. File Handling with Errors

try:
    with open("example.txt", "r") as file:
        content = file.read()
except FileNotFoundError:
    print("File not found!")

2. Handling User Input

try:
    number = int(input("Enter a number: "))
except ValueError:
    print("Please enter a valid number.")

Practice Exercises

1. Temperature Conversion Program

Write a program to convert temperature from Celsius to Fahrenheit, handling invalid inputs.

try:
    celsius = float(input("Enter temperature in Celsius: "))
    fahrenheit = (celsius * 9/5) + 32
    print(f"Temperature in Fahrenheit: {fahrenheit}")
except ValueError:
    print("Invalid input! Please enter a numeric value.")