Python Basics: Your First Steps Into Programming
Error Handling
Lesson 15 of 16 • 10 XP
Keep your place in this quest
Log in or sign up for free to subscribe, follow lesson progress, and access more learning content.
Errors are inevitable in any program, and Python offers several ways to deal with them.
Error handling is crucial to ensure your program can continue running safely and efficiently, even when something unexpected happens.
In this lesson, we’ll explore the different types of errors, how to handle them, how to raise your own, and how to ensure important cleanup tasks are always executed.
Types of Errors in Python
Before we learn how to handle errors, we need to understand the two main categories:
-
Syntax Errors: These occur when the Python code is not syntactically correct. They’re caught by the Python interpreter before the program runs.
Example: forgetting a colon after anifstatement. -
Exceptions: These happen while the program is running when something unexpected occurs — for example, dividing a number by zero or trying to access an invalid index in a list.
Handling Exceptions with try and except
The most common way to handle exceptions in Python is with try/except blocks:
- The try block contains the code that might cause an exception.
- The except block contains the code to run if an exception is raised.
Example:
try:
file = open("file.txt", "r")
content = file.read()
print(content)
except IOError:
print("The file could not be opened.")
Here:
- If
"file.txt"doesn’t exist or can’t be opened, Python raises anIOError. - The
exceptblock catches it and prints a friendly message instead of crashing.
TIP: Keep the try block as small as possible — only include the code that might fail, not unrelated logic.
Handling Multiple Exception Types
You can handle different exception types separately by using multiple except blocks:
try:
# code that may raise exceptions
except TypeError:
# handle type errors
except ValueError:
# handle value errors
except:
# handle any other exceptions
The last bare except catches any unhandled exceptions — but use it with care, as it can hide bugs you didn’t expect.
Raising Your Own Exceptions
Sometimes your program needs to signal that something went wrong — even if Python wouldn’t normally see it as an error.
You can raise exceptions using the raise statement.
Example:
def divide(a, b):
if b == 0:
raise ValueError("The second argument cannot be zero")
return a / b
print(divide(10, 2)) # 5.0
print(divide(10, 0)) # ValueError: The second argument cannot be zero
This lets you define clear error messages and stop execution when invalid data is encountered.
The finally Block
The finally block defines code that always runs — whether or not an exception occurred.
It’s often used to release resources such as files or database connections.
Example:
try:
file = open("file.txt", "r")
content = file.read()
print(content)
finally:
file.close()
Even if reading the file caused an error, the finally block ensures the file is closed.
IMPORTANT!: Always close files and free resources in a finally block (or use the "with" statement) to avoid leaks.
Got it — here’s an additional section you can append to the Error Handling lesson, explaining why “try/except everything” is a bad practice and when targeted exception handling is the right choice.
Avoid Catching Every Exception Without a Reason
A common beginner mistake is to wrap huge chunks of code in a single try/except block that catches everything — or even worse, to just use a bare except: without specifying the error type.
Example of bad practice:
try:
# a lot of unrelated code here
except:
pass # silently ignores all errors
Why this is dangerous:
- Hides bugs: Real mistakes in your code will be ignored, making them harder to find.
- Masks the cause: You lose information about what actually failed.
- May cause unexpected behavior: The program keeps running in an invalid state.
When to Use Broad Exception Handling
Catching all exceptions (except Exception:) should be rare and intentional.
Examples where it might be appropriate:
- Top-level error logging in a program, to prevent a crash and write the error to a log file.
- Fail-safe loops in services that must keep running (but still log/report the error before continuing).
- Temporary debugging to quickly see if anything is going wrong — but only as a short-term tool.
Best Practice
- Be specific: Catch only the exceptions you expect and know how to handle.
- Keep try blocks small: Wrap only the code that can fail, not entire functions.
- Always log or handle the exception meaningfully — don’t just “pass” and forget it.
By being selective, you make your code easier to debug, safer to run, and much more predictable.
Wrapping Up
Error handling is a fundamental part of Python programming:
- It prevents unexpected crashes.
- It allows you to deal with problems gracefully.
- It makes your code more robust, reliable, and safe.
By mastering exceptions, raising custom errors, and using finally, you’ll write programs that are better prepared for the real world.