Skip to content

else and finally in Exception Handling

diagram the four blocks, and exactly when each runs mermaid
else runs only when the try body finished without raising, which makes it the right place for code that must not be protected by the except. finally runs on every path -- normal exit, handled exception, unhandled exception, and even a return. That last case is where it turns dangerous.

else runs only if no exception occurred.

try_else.py
try:
    x = int("42")
except ValueError:
    print("Invalid number")
else:
    print("Parsed successfully:", x)

finally runs always (success or error). This is useful for cleanup.

try_finally.py
f = None
try:
    f = open("data.txt", "r")
    print(f.read())
except FileNotFoundError:
    print("File not found")
finally:
    if f is not None:
        f.close()
        print("File closed")

Instead of manual .close(), use with.

with_open.py
try:
    with open("data.txt", "r") as f:
        print(f.read())
except FileNotFoundError:
    print("File not found")
  • closing files
  • releasing locks
  • closing DB connections
  • cleaning up temporary files
sketch Which block runs, and what a return in finally does to an exception p5.js
Three paths through the same statement. The left column is the ordinary case, the middle is a caught exception, and the right is the one worth remembering: a return inside finally discards whatever was in flight, including an exception nobody has handled. Python 3.14 now warns about it at compile time.
pch.quizTag pch.quizDefaultTitle
  1. A function raises inside `try` and has `return 'done'` inside `finally`. What does the caller see?

    pch.quizShowAnswer

    B — `'done'` — the exception is discarded — Verified: the ValueError vanished entirely, with no traceback and nothing logged. Python 3.14 now warns at compile time — SyntaxWarning: 'return' in a 'finally' block.

  2. When does the `else` clause of a `try` statement run?

    pch.quizShowAnswer

    C — Only when the `try` body did NOT raise — `else` is the no-exception path. Putting that code at the end of `try` instead would leave it guarded by the `except`, so an unrelated error in it would be caught by a handler meant for the risky call.

  3. With no exception raised, which blocks run and in what order?

    pch.quizShowAnswer

    B — `try`, `else`, `finally` — Verified. With an exception it is `try`, `except`, `finally` instead — `finally` runs on every path.

  4. What should `finally` be used for?

    pch.quizShowAnswer

    B — Cleanup that must happen on every path — Releasing a lock, closing a handle, restoring state. Changing what the function returns from there is what silently swallows exceptions.

pch.coffeeTagline

pch.coffeeCta

pch.feedbackHeading

pch.feedbackSubheading