Exception Handling in Python
Mastering Exception Handling in Python: A Comprehensive Guide
Section titled “Mastering Exception Handling in Python: A Comprehensive Guide”Errors are unavoidable in real programs — a file may be missing, a user may type text where a number was expected, or a network call may fail. Exception handling is the mechanism Python provides to detect these errors and respond to them gracefully instead of crashing. In this guide, we’ll explore the try, except, else, and finally blocks, the raise keyword, and how to build your own custom exceptions.
What is an Exception?
Section titled “What is an Exception?”An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions. When Python encounters an error it cannot handle, it raises an exception. If the exception is not handled, the program stops and prints a traceback.
# An unhandled exception
print(10 / 0)Output:
C:\Users\Your Name> python error.py
Traceback (most recent call last):
File "error.py", line 2, in <module>
print(10 / 0)
ZeroDivisionError: division by zeroThe program never reaches any code after line 2 — the ZeroDivisionError terminates it. Exception handling lets us catch that error and continue.
Errors vs. Exceptions
Section titled “Errors vs. Exceptions”- Syntax errors are mistakes in the structure of the code (a missing colon, an unclosed bracket). They are caught before the program runs and cannot be handled at runtime.
- Exceptions are raised while the program runs. These are the errors we handle with
try/except.
# Syntax error - cannot be caught with try/except
if True
print("missing colon")The try-except Block
Section titled “The try-except Block”The try block contains code that might raise an exception. The except block contains the code that runs if an exception occurs.
The syntax of the try-except block in Python is as follows:
try:
# code that might raise an exception
except ExceptionType:
# code that runs if the exception occursDiagram:
graph TD
A[Start] --> B[Run try block]
B --> C{Exception raised?}
C -->|No| D[Skip except block]
C -->|Yes| E[Run except block]
D --> F[End]
E --> F[End]
The following example demonstrates how to catch a ZeroDivisionError:
try:
result = 10 / 0
print(result)
except ZeroDivisionError:
print("You cannot divide by zero!")Output:
C:\Users\Your Name> python try_except.py
You cannot divide by zero!In the above example, the division raises a ZeroDivisionError. Python jumps to the matching except block, prints the message, and the program continues normally instead of crashing.
Catching the Exception Object
Section titled “Catching the Exception Object”You can capture the exception object itself using the as keyword. This gives you access to the error message.
try:
number = int("hello")
except ValueError as error:
print("Conversion failed:", error)Output:
C:\Users\Your Name> python as_keyword.py
Conversion failed: invalid literal for int() with base 10: 'hello'Handling Multiple Exceptions
Section titled “Handling Multiple Exceptions”A single try block can be followed by several except blocks. Python runs the first one that matches the raised exception.
try:
value = int(input("Enter a number: "))
result = 100 / value
print(result)
except ValueError:
print("That was not a valid number.")
except ZeroDivisionError:
print("You cannot divide by zero.")You can also handle several exception types in one block by passing a tuple:
try:
risky_operation()
except (ValueError, TypeError, KeyError) as error:
print("Something went wrong:", error)The else Clause
Section titled “The else Clause”The else block runs only if no exception was raised in the try block. It is useful for code that should run after a successful try, keeping the try block focused on the risky operation alone.
try:
number = int("42")
except ValueError:
print("Invalid number.")
else:
print("Conversion succeeded:", number)Output:
C:\Users\Your Name> python else_clause.py
Conversion succeeded: 42The finally Clause
Section titled “The finally Clause”The finally block runs no matter what — whether or not an exception was raised, and even if a return statement executes. It is used for cleanup tasks such as closing files or releasing resources.
try:
file = open("data.txt", "r")
data = file.read()
except FileNotFoundError:
print("File not found.")
finally:
print("Cleaning up...")Diagram:
graph TD
A[Start] --> B[Run try block]
B --> C{Exception?}
C -->|No| D[Run else block]
C -->|Yes| E[Run except block]
D --> F[Run finally block]
E --> F[Run finally block]
F --> G[End]
The raise Keyword
Section titled “The raise Keyword”You can deliberately raise an exception using the raise keyword. This is useful for signalling that something is wrong with the input to your function.
def set_age(age):
if age < 0:
raise ValueError("Age cannot be negative")
print("Age set to", age)
set_age(-5)Output:
C:\Users\Your Name> python raise.py
Traceback (most recent call last):
...
ValueError: Age cannot be negativeRe-raising an Exception
Section titled “Re-raising an Exception”Inside an except block, a bare raise re-raises the current exception after you have done some work (such as logging).
try:
risky()
except ValueError:
print("Logging the error before re-raising...")
raiseCustom Exceptions
Section titled “Custom Exceptions”You can define your own exception types by subclassing the built-in Exception class. Custom exceptions make your code more readable and let callers catch your specific error.
class InsufficientFundsError(Exception):
"""Raised when a withdrawal exceeds the available balance."""
pass
def withdraw(balance, amount):
if amount > balance:
raise InsufficientFundsError(
f"Cannot withdraw {amount}; balance is only {balance}"
)
return balance - amount
try:
withdraw(100, 250)
except InsufficientFundsError as error:
print("Transaction failed:", error)Output:
C:\Users\Your Name> python custom_exception.py
Transaction failed: Cannot withdraw 250; balance is only 100Common Built-in Exceptions
Section titled “Common Built-in Exceptions”| Exception | Raised when |
|---|---|
ValueError | A function gets an argument of the right type but wrong value (e.g. int("abc")). |
TypeError | An operation is applied to an object of the wrong type. |
KeyError | A dictionary key is not found. |
IndexError | A sequence index is out of range. |
FileNotFoundError | A file or directory is requested but does not exist. |
ZeroDivisionError | The second argument of a division or modulo is zero. |
AttributeError | An attribute reference or assignment fails. |
ImportError | An import statement fails to find the module. |
Conclusion
Section titled “Conclusion”Exception handling lets your programs respond to errors gracefully instead of crashing. The try block holds risky code, except handles failures, else runs on success, and finally always runs for cleanup. The raise keyword lets you signal errors, and custom exception classes make your error handling expressive and precise. Master these tools and your Python programs will be far more robust. For more hands-on examples and in-depth tutorials, explore our resources on Python Central Hub!
Try it: Exception Handling Exercises
Section titled “Try it: Exception Handling Exercises”Exercise 1 – Catch a ZeroDivisionError
Section titled “Exercise 1 – Catch a ZeroDivisionError”Exercise 2 – try / except / else / finally
Section titled “Exercise 2 – try / except / else / finally”Exercise 3 – Raise a Custom Exception
Section titled “Exercise 3 – Raise a Custom Exception”pch.coffeeTagline
pch.coffeeCtapch.feedbackHeading
pch.feedbackSubheading