Handling errors with exceptions
Programs that work with files, data, and the outside world eventually encounter situations they cannot control. A file may be missing. Data may not be in the expected shape. A calculation may fail at runtime. Python includes a structured way to deal with these situations so a program can respond deliberately instead of stopping abruptly.
This lesson exists to introduce that structure and show how it fits into real programs that do useful work.
Errors and exceptions
An error is a problem that occurs while a program is running. In Python, these problems are represented as exceptions. An exception is an object that signals something has gone wrong and interrupts normal execution.
If an exception is not handled, the program stops and Python reports what happened. Handling exceptions gives us a way to intercept that signal and decide what to do next.
Handling runtime errors with try and except
Python handles exceptions using a try and except block. Code that might fail is placed inside try. Code that responds to the failure goes in except.
If no exception occurs, the except block is skipped. If an exception occurs, normal execution stops and control jumps to except.
try:
with open("planets.html", "r") as file:
html = file.read()
except:
html = "<p>No planet data available.</p>"
This structure allows the program to keep going even when a runtime error occurs.
Catching specific exception types
Not all exceptions mean the same thing. Python provides different exception types to describe different failures. Catching a specific type makes the program’s intent clearer.
A missing file, for example, raises FileNotFoundError.
try:
with open("moons.html", "r") as file:
html = file.read()
except FileNotFoundError:
html = "<p>No moon data found.</p>"
By naming the exception type, the program responds only to that specific situation and allows other exceptions to surface normally.
Executing cleanup code after errors
Some work must happen whether an error occurs or not. Python supports this using a finally block. Code inside finally always runs after try and except complete.
This is commonly used for cleanup tasks.
file = None
try:
file = open("index.html", "w")
file.write("<h1>Solar System</h1>")
except IOError:
pass
finally:
if file:
file.close()
This structure guarantees that cleanup logic runs even if an exception interrupts execution.
Using exceptions to prevent program crashes
Handled exceptions prevent programs from crashing unexpectedly. Instead of stopping, the program can choose a safe fallback, produce partial output, or continue with reduced functionality.
In a static site generator, this might mean skipping a page that failed to generate while still producing the rest of the site.
for page in pages:
try:
page.write()
except Exception:
continue
Exceptions become part of the program’s control flow rather than a fatal event.
Conclusion
Exceptions are how Python reports runtime problems, and try and except provide a way to respond to them deliberately. By catching specific exception types, running cleanup code reliably, and choosing how failures affect execution, programs can remain stable and predictable.
With this mental model in place, errors stop being mysterious interruptions and become another tool for building robust Python systems.