Exception Handling in Python
Subject: Data Structures and Algorithms · Language: Python · Level: beginner · 7 min read
Learn Python errors, exceptions, try, except, else, finally, raise, common exceptions, and safe DSA error handling habits.
An exception is a problem that happens while a program is running. The syntax may be correct, but the program can still fail because of invalid input, division by zero, invalid index, missing key, or wrong type conversion.
Exception handling lets the program respond to such problems without crashing suddenly. The `try` block contains risky code. The `except` block runs when a matching exception occurs. This gives the programmer a chance to show a clear message or recover safely.
Common Python exceptions include `ZeroDivisionError`, `ValueError`, `IndexError`, `KeyError`, and `TypeError`. Reading the exception name is very useful because it usually tells what kind of mistake happened.
For DSA problems, students should not wrap every line in `try except`. It is usually better to prevent errors with correct conditions. For example, check that a list is not empty before reading the first element, and check that a divisor is not zero before division.
The `finally` block runs whether an exception happens or not. It is useful for cleanup tasks such as closing files. In beginner coding problems, `finally` is not used very often, but it is important in real applications.
A good debugging habit is to trace the value that caused the exception. If an index error happens, check the list length and the index value. If a value conversion error happens, check the exact input string.
Exception handling helps a Python program respond to such problems in a controlled way instead of stopping suddenly with a long error message.
For beginners, exception handling is important because it teaches the difference between normal flow and error flow. Normal flow means the program runs as expected. Error flow means something unusual happened and the program needs a backup response.
Error vs Exception
An error is a general problem in a program. Some errors happen before the program runs, and some happen while the program is running.
A syntax error happens when Python cannot understand the code structure. For example, forgetting a colon after `if` causes a syntax error.
An exception usually happens while the program is running. For example, dividing by zero causes a `ZeroDivisionError`.
Why Exception Handling Is Needed
A program should not crash suddenly when a predictable problem happens. If a user enters zero as a divisor, the program should show a clear message instead of exposing a traceback.
Exception handling makes programs more stable, user-friendly, and easier to debug.
try Block
The `try` block contains code that may cause an exception. Python first tries to run this code normally.
```python
try:
result = a // b
```
If no exception occurs, the code runs normally. If an exception occurs, Python jumps to the matching `except` block.
except Block
The `except` block handles the exception. It runs only when the matching exception occurs inside the `try` block.
```python
try:
result = a // b
except ZeroDivisionError:
print("Division by zero is not allowed")
```
Sample Output when `a = 10` and `b = 0`
```text
Division by zero is not allowed
```
Here, if `b` is zero, Python raises `ZeroDivisionError`, and the `except` block prints a clear message.
Handling Multiple Exceptions
Sometimes different problems can happen in the same block. You can write multiple `except` blocks.
```python
try:
n = int(input())
print(10 // n)
except ValueError:
print("Please enter a valid number")
except ZeroDivisionError:
print("Division by zero is not allowed")
```
Sample Input
```text
0
```
Output
```text
Division by zero is not allowed
```
This makes the response more specific. A wrong number format and division by zero are different problems, so they get different messages.
Generic except
A generic `except` can catch many exceptions, but beginners should use it carefully.
```python
try:
risky_code()
except Exception as error:
print("Something went wrong")
```
Sample Output if `risky_code()` fails
```text
Something went wrong
```
Catching every exception without understanding it can hide bugs. It is usually better to catch the specific exception you expect.
else Block
The `else` block runs only when no exception occurs in the `try` block.
```python
try:
result = a // b
except ZeroDivisionError:
print("Division by zero is not allowed")
else:
print("Result =", result)
```
Sample Output when `a = 10` and `b = 2`
```text
Result = 5
```
This keeps successful logic separate from error handling logic.
finally Block
The `finally` block runs whether an exception occurs or not. It is commonly used for cleanup work such as closing files, releasing resources, or printing completion messages.
```python
try:
result = a // b
except ZeroDivisionError:
print("Division by zero is not allowed")
finally:
print("Program completed")
```
Sample Output when `a = 10` and `b = 0`
```text
Division by zero is not allowed
Program completed
```
The `finally` block is not required in every program, but it is useful when some action must happen in all cases.
raise Keyword
The `raise` keyword is used to create an exception manually. It is useful when a value is invalid and the program should clearly report the problem.
```python
age = -5
if age < 0:
raise ValueError("Age cannot be negative")
```
This kind of validation is common in real projects. Beginner programs usually start with `try` and `except` first.
Common Exceptions in Python
- `ZeroDivisionError` occurs when dividing by zero
- `ValueError` occurs when a value has the wrong format, such as `int("abc")`
- `IndexError` occurs when an invalid list or string index is used
- `KeyError` occurs when a missing dictionary key is accessed
- `TypeError` occurs when an operation is used with the wrong data type
- `FileNotFoundError` occurs when a file path does not exist
Understanding common exception names helps students debug programs faster. When Python shows an exception, read the name carefully because it usually tells what went wrong.
Exception Handling in DSA
In DSA problems, we do not usually wrap every line in `try except`. Instead, we write correct conditions to avoid exceptions.
For example, check that a divisor is not zero before division, check indexes before accessing a list, and handle empty lists before calling `max()` or `min()`.
Still, learning exception handling is useful because it helps you understand runtime errors and fix them properly.
Example Program
```python
a = int(input("Enter first number: "))
b = int(input("Enter second number: "))
try:
print("Result =", a // b)
except ZeroDivisionError:
print("Division by zero is not allowed")
print("Program completed")
```
Sample Input
```text
10
0
```
Output
```text
Enter first number: Enter second number: Division by zero is not allowed
Program completed
```
This program tries to divide two numbers. If the second number is zero, the `except` block prints a friendly message. The final line still runs, so the user knows the program completed.
Best Practices
Catch specific exceptions when possible. Keep the `try` block small so it is clear which line may fail. Do not hide errors silently. Print or handle errors in a way that helps the user or programmer understand the problem.
In coding interviews, focus on preventing errors with correct logic. Use exception handling when the problem specifically involves invalid input or runtime safety.
For beginners, it is important to understand that exception handling is not a replacement for good logic. In DSA, we usually avoid errors by writing correct conditions, such as checking that a list is not empty before accessing the first element.
A good debugging habit is to find the line that caused the exception and then ask why the value was invalid at that moment. This turns error messages into useful clues instead of something to fear.
Practice Question
Take two numbers and divide them. If the second number is zero, print a proper error message. Then update the program to always print `Program completed` at the end.