Chapter 9: Error and Exception Handling
Errors and exceptions are inevitable in programming. Python provides a robust mechanism for handling errors gracefully to ensure programs can recover and continue execution where possible.
Types of Errors
Syntax Errors:
Occur when the code violates Python’s grammar rules.
Example:
print("Hello") # Correct print("Hello" # SyntaxError: unexpected EOF while parsing
Runtime Errors:
Occur during the execution of a program.
Example:
result = 10 / 0 # ZeroDivisionError
Logical Errors:
Errors in the program’s logic that produce incorrect results without causing crashes.
Example:
# Intended to calculate the average total = 100 count = 0 average = total / count # ZeroDivisionError
Handling Exceptions
Python uses try...except
blocks to handle exceptions.
Syntax:
try:
# Code that might raise an exception
except ExceptionType:
# Code to handle the exception
finally:
# Code that executes regardless of an exception (optional)
Example:
try:
num = int(input("Enter a number: "))
result = 10 / num
print("Result:", result)
except ZeroDivisionError:
print("Cannot divide by zero.")
except ValueError:
print("Invalid input. Please enter a number.")
finally:
print("Execution completed.")
The else
Clause
else
ClauseThe else
block executes if no exceptions are raised in the try
block.
Example:
try:
num = int(input("Enter a number: "))
print("You entered:", num)
except ValueError:
print("That’s not a valid number.")
else:
print("Success! No errors occurred.")
Raising Exceptions
Use the raise
keyword to generate exceptions intentionally.
Example:
def validate_age(age):
if age < 0:
raise ValueError("Age cannot be negative.")
print("Valid age.")
try:
validate_age(-5)
except ValueError as e:
print("Error:", e)
Creating Custom Exceptions
You can define your own exceptions by subclassing the built-in Exception
class.
Example:
class NegativeNumberError(Exception):
def __init__(self, value):
self.value = value
try:
num = int(input("Enter a positive number: "))
if num < 0:
raise NegativeNumberError(num)
except NegativeNumberError as e:
print(f"Negative numbers are not allowed: {e.value}")
Common Built-in Exceptions
Exception
Description
ValueError
Raised when a function receives an invalid argument.
TypeError
Raised when an operation is performed on an inappropriate type.
ZeroDivisionError
Raised when dividing by zero.
KeyError
Raised when a key is not found in a dictionary.
IndexError
Raised when an index is out of range.
FileNotFoundError
Raised when a file operation fails because the file doesn’t exist.
Example:
try:
my_dict = {"name": "Alice"}
print(my_dict["age"])
except KeyError:
print("Key not found.")
Logging Exceptions
Use the logging
module to record errors and exceptions for debugging and analysis.
Example:
import logging
logging.basicConfig(filename="app.log", level=logging.ERROR)
try:
result = 10 / 0
except ZeroDivisionError as e:
logging.error("Exception occurred", exc_info=True)
Exercises
Exercise 1:
Write a program to take two numbers as input and perform division. Handle ZeroDivisionError
and ValueError
exceptions.
Solution:
try:
num1 = int(input("Enter numerator: "))
num2 = int(input("Enter denominator: "))
result = num1 / num2
print("Result:", result)
except ZeroDivisionError:
print("Error: Cannot divide by zero.")
except ValueError:
print("Error: Invalid input. Please enter numbers only.")
Exercise 2:
Create a custom exception OutOfRangeError
that is raised when a number is not between 1 and 100.
Solution:
class OutOfRangeError(Exception):
pass
try:
num = int(input("Enter a number between 1 and 100: "))
if num < 1 or num > 100:
raise OutOfRangeError("Number out of range.")
print("Valid number.")
except OutOfRangeError as e:
print("Error:", e)
Exercise 3:
Write a program that logs errors to a file instead of printing them to the console.
Solution:
import logging
logging.basicConfig(filename="errors.log", level=logging.ERROR)
try:
num = int(input("Enter a number: "))
result = 10 / num
except Exception as e:
logging.error("Error occurred: %s", e)
print("An error occurred. Check errors.log for details.")
Best Practices
Use specific exception types instead of a generic
except
clause.Keep the
try
block small and focused.Log exceptions for debugging and maintenance.
Avoid using exceptions for normal control flow.
Use custom exceptions to represent specific error cases in your application.
In the next chapter, we will explore working with databases using Python, including basic CRUD operations and interacting with sqlite3
.
Last updated