Concepts / Raising and catching custom exceptions

Raising and catching custom exceptions

The decision is made by what happens inside try. A successful completion selects else; an exception selects a matching except block.

  • Programming
Interactive lab

Try it: try / except / else / finally

How an exception jumps out of a try block to the first matching except clause, when else runs, and why finally always runs.

How it works

  1. Statements in try run until one raises an exception; the rest of try is skipped.
  2. Python checks the except clauses in order and runs the first one whose type matches.
  3. If nothing was raised, the else block runs instead.
  4. finally runs in every case.

Default run (9 steps): Call safe_divide('4'). … Return 25.0. Output was: Worked: 25.0 / Done.

Simplified: One fixed function; int() and / are modelled exactly (including how Python prints floats), but nothing is executed as Python.

Educational simulation

Loading the simulation…

The Success Path Matters

Exception handling has two broad outcomes: the risky operation either succeeds or raises an exception. A try-except-else structure makes those outcomes explicit. The try block contains the operation being attempted, except blocks respond to particular exception types, and the optional else block contains code for the success path. The key rule is that else runs only when the try block finishes without raising an exception.

The Execution Route

Python evaluates the try block first. If the operation succeeds, Python skips the except blocks and enters else. If the operation raises an exception, Python immediately looks for a matching except block. After the matching handler runs, the else block is skipped. This means there is no route in which an exception is handled and then else also runs.

tryrisky operationExceptionraised?elsesuccess pathexceptmatching handlercompletenoyes
What code block executes next when the try block succeeds versus when it raises an exception?
Key point

The decision is made by what happens inside try. A successful completion selects else; an exception selects a matching except block.

Why Else Is Separate

You could place success-path statements directly after the risky operation inside try, but then those statements are also being monitored by the exception handlers. If one of them raises an exception, the except blocks may handle it even though the original risky operation succeeded. Placing success-only logic in else separates the operation being monitored from the code that should run after successful completion.

try beginsrisky operation startstry succeedsno exceptionelsesuccess logicexception raisedtry stopsexcept handlererror logiccompletes normallyenterraisesmatch
Why does the else block execute only when the try block completes without raising an exception?
Best practice

Keep error-handling logic in except blocks and success-path logic in else. This makes the intended route clear and avoids accidentally treating an exception from later success code as though it came from the original risky operation.

Separate Responses for Separate Events

A try block can have multiple except blocks. Each one names a specific exception type and can provide a different response. Python checks these handlers from top to bottom and executes the first one whose exception type matches. The remaining except blocks are skipped.

input attemptinside tryEOFErrorfirst handlerEOFError handlerspecific responseKeyboardInterruptnext handlerKeyboardInterrupthandlerspecific responseelseordinary inputevent occursmatchesdoes not matchmatchesno exception
How does control flow choose between the EOFError handler and the KeyboardInterrupt handler?

Tracing User Input

Worked example

Three possible input outcomes

A program attempts to read text from a user. Its structure has a try block for the input operation, one except block for EOFError, a second except block for KeyboardInterrupt, and an else block that displays the entered text. Which part runs in each situation?

  1. 1
    Ordinary text

    The user enters text. The input operation completes without raising an exception, so both except blocks are skipped and else runs.

  2. 2
    End-of-file signal

    The user sends an end-of-file signal, such as Ctrl+D on Unix/Linux or Ctrl+Z on Windows. EOFError is raised, the EOFError handler runs, and else is skipped.

  3. 3
    Keyboard interrupt

    The user presses Ctrl+C. KeyboardInterrupt is raised, the KeyboardInterrupt handler runs, and else is skipped.

Result

Normal text selects else. An end-of-file signal selects the EOFError handler. Ctrl+C selects the KeyboardInterrupt handler.

SituationException raisedBlock that runsDoes else run?
User enters textNoneelseYes
User sends an end-of-file signalEOFErrorEOFError except blockNo
User presses Ctrl+CKeyboardInterruptKeyboardInterrupt except blockNo

Execution outcomes for the input-handling pattern

Key point

The else block does not mean that no input event occurred. It means the try block completed normally. Ordinary text therefore reaches else, while either interruption reaches its matching except block.

Mistakes Beginners Make

  • Common mistake

    Assuming else always runs after try.

    What it looks like

    An end-of-file signal raises EOFError, but the learner still expects the success message in else.

    Why it fails

    When an exception is raised, Python moves to the matching except block and skips else.

    Do this instead

    Ask first whether try completed without an exception. Only that outcome reaches else.

  • Common mistake

    Treating all failures as one indistinguishable case.

    What it looks like

    EOFError and KeyboardInterrupt are handled as though they require the same response.

    Why it fails

    Different exception types can represent different events and can be handled by separate except blocks.

    Do this instead

    Use a specific except block for each exception type that needs a different response.

  • Common mistake

    Putting success-path logic in try without considering its monitoring scope.

    What it looks like

    Code that should run only after successful input is placed inside try after the input operation.

    Why it fails

    That code is also monitored by the except blocks. An exception from it may be handled as though it came from the input operation.

    Do this instead

    Place success-only logic in else when separating it from the risky operation improves clarity and correctness.

  • Common mistake

    Expecting more than one matching except block to run.

    What it looks like

    A learner expects Python to continue checking handlers after it finds a match.

    Why it fails

    Python executes the first matching except block and skips the remaining except blocks.

    Do this instead

    Read except blocks from top to bottom and stop at the first match.

Practice the Prediction

What do you think happens?

A try block attempts to get user input. The user presses Ctrl+C. Which block executes next?

  • The EOFError handler

  • The KeyboardInterrupt handler

  • The else block

  • Both except handlers

Reveal answer
Answer:

The KeyboardInterrupt handler

Ctrl+C raises KeyboardInterrupt. Python checks the except blocks in order, selects the first matching KeyboardInterrupt handler, and skips else and the remaining handlers.

MEDIUM

For each situation, predict the next block before checking the explanation: the user enters ordinary text; the user sends an end-of-file signal; the try operation completes normally but the learner expects both an except block and else to run.

Hints
  • Start by identifying whether the try operation raises an exception.
  • If an exception is raised, identify its type and find the matching handler.
  • Remember that else is reserved for normal completion.

Key Takeaways

  1. 1
    The try block runs first and contains the operation being monitored for exceptions.
  2. 2
    Python selects the first except block whose exception type matches the raised exception.
  3. 3
    The else block runs only when try completes without raising an exception.
  4. 4
    EOFError and KeyboardInterrupt can have separate handlers with tailored responses.
  5. 5
    Keeping success logic in else separates it from the code whose exceptions should be handled.

At a glance

  • The else block represents successful completion of try, not a block that always follows it.
  • An exception sends control to the first matching except block and skips else.
  • Multiple specific except blocks allow different responses for EOFError and KeyboardInterrupt.
  • Predicting control flow starts by classifying the event: normal completion, EOFError, or KeyboardInterrupt.
  • Separating success logic into else keeps the exception-monitoring boundary clear.

Related concepts

More concepts starting with R