HomeGuidesPythonPython Error Handling — try/except/else/finally with Code Examples
🐍 Python

Python Error Handling: try, except, else, finally Explained

Error handling is tested on every Python exam. Here's the full picture — what each clause does, when to use it, and the traps to avoid.

Examifyr·2026·5 min read

try / except basics

Code in the try block runs first. If an exception occurs, Python looks for a matching except clause.

try:
    result = 10 / 0
except ZeroDivisionError:
    print("Cannot divide by zero")

# Catching multiple exception types
try:
    val = int("abc")
except (ValueError, TypeError) as e:
    print(f"Error: {e}")

# Catch any exception (use sparingly)
try:
    risky_operation()
except Exception as e:
    print(f"Something went wrong: {e}")
Note: Never use bare `except:` — it silently swallows KeyboardInterrupt and SystemExit too. Always use `except Exception` at minimum.

else and finally

The else clause runs only if no exception was raised. The finally clause always runs — even if there's a return statement in try or except.

try:
    result = 10 / 2
except ZeroDivisionError:
    print("Division error")
else:
    print(f"Result: {result}")  # runs — no exception
finally:
    print("Always runs")        # runs no matter what

# finally even overrides return:
def test():
    try:
        return "try"
    finally:
        return "finally"  # this is what gets returned!

print(test())  # "finally"
Note: The finally-overrides-return behaviour is a guaranteed exam question. The return in finally replaces the return in try.

Raising exceptions

Use `raise` to throw an exception. You can re-raise the current exception with bare `raise`.

def set_age(age):
    if age < 0:
        raise ValueError(f"Age cannot be negative: {age}")
    return age

try:
    result = risky()
except Exception as e:
    log_error(e)
    raise  # re-raises the same exception

Custom exception classes

Create custom exceptions by subclassing Exception.

class InsufficientFundsError(Exception):
    def __init__(self, balance, amount):
        self.balance = balance
        self.amount = amount
        super().__init__(f"Need {amount}, have {balance}")

def withdraw(balance, amount):
    if amount > balance:
        raise InsufficientFundsError(balance, amount)
    return balance - amount

try:
    withdraw(50, 100)
except InsufficientFundsError as e:
    print(e)  # "Need 100, have 50"

Exception hierarchy

Python exceptions form a class hierarchy. Catching a parent class catches all its children too.

# Hierarchy (partial):
# BaseException
#   SystemExit, KeyboardInterrupt
#   Exception
#     ValueError, TypeError, KeyError
#     ArithmeticError -> ZeroDivisionError
#     LookupError -> IndexError, KeyError

# Order matters — specific before general:
try:
    int("bad")
except ValueError:
    print("caught ValueError")
except Exception:
    print("caught something else")
Note: Order matters in multiple except clauses. Put specific exceptions before general ones.

Exam tip

The else/finally distinction is the most common exam question on this topic. else = no exception occurred; finally = runs regardless. Also know that finally with a return statement overrides any earlier return.

🎯

Think you're ready? Prove it.

Take the free Python readiness test. Get a score, topic breakdown, and your exact weak areas.

Take the free Python test →

Free · No sign-up · Instant results

← Previous
Python Classes and OOP Explained — __init__, Inheritance & Methods
Next →
Python String Methods — Complete Reference with Code Examples
← All Python guides