Handling Expected Errors

Some failures are expected at a program boundary. A narrow try block and a specific except clause can turn those known exceptions into an explicit result without hiding unrelated bugs.

Some operations can fail for reasons a program expects. Text entered into a program may not represent a valid number, or a requested dictionary key may be absent. Python raises an exception when such an operation cannot finish normally.

A try and except statement lets the program define what to do for a specific expected exception:

Python first runs the indented try block. int("eight") raises ValueError, so the remaining statements in that block are skipped. Python finds the matching except ValueError clause and runs its body.

Handle Only a Failure You Understand

The exception type states which failure the program is prepared to handle:

This code handles invalid integer text. It does not replace missing or malformed data with a number that could be mistaken for a real score.

A broad handler hides evidence:

The bare except clause catches almost every exception, including mistakes unrelated to conversion. Prefer a specific type such as ValueError, KeyError, or IndexError when that failure is part of the program's expected behavior.

Keep the try Block Narrow

Place only the operation whose expected failure you intend to catch inside the try block:

The else block runs only when the try block finishes without an exception. Keeping later computation in else makes it clear that the handler covers the conversion, not every operation in the program.

Handle one expected conversion failure

Run the program with valid and invalid text. Observe which block runs in each case.

Ready to run.

An Unmatched Exception Remains Visible

An except clause runs only when its exception type matches the failure. This handler is prepared for invalid integer text:

If the try block instead raises NameError, the ValueError handler does not run. Python continues looking outward for a matching handler. If none exists, the program stops and displays the traceback.

This is useful. A specific handler responds to the failure the program understands while preserving evidence about unexpected defects.

The Handler Can Inspect the Exception

Use as to give the exception object a local name:

The name error is available inside the handler. Its message can help with diagnosis or logging. A message shown to a user should still explain what input is needed rather than exposing an internal traceback without context.

Different Exceptions Need Different Decisions

One try statement may have specific handlers for different expected failures:

KeyError means the requested name is absent. ValueError means the key exists but its text cannot be converted. These failures require different explanations and possibly different recovery behavior.

Python tests the except clauses from top to bottom and runs the first matching one. Use separate, specific exception types so each expected failure receives the appropriate response. Avoid placing a broad except Exception before specific handlers, because it would match them first and make the later clauses unreachable.

Handling Is Not the Same as Fixing

An exception handler is appropriate when the failure is expected at a boundary and the program has a meaningful response. It is not a substitute for fixing a programming mistake:

Catching the resulting NameError would hide the typo. Correct the name instead.

Ask two questions:

  1. Can this operation fail during normal use even when the program is written correctly?
  2. Does the program know what result or message should follow that failure?

If both answers are yes, handling may be appropriate. Otherwise, keep the exception visible and debug its cause.

Do Not Use Exceptions for Ordinary Branches

Use a normal condition when the program can test the state directly and the condition is part of ordinary control flow:

Both a membership check and a KeyError handler can be valid. The condition often reads more directly when absence is common and easy to test. Exception handling becomes especially useful around operations such as conversion and file access, where attempting the operation is the clearest test.

Exercise: Choose a specific exception

Which exception should handle int("eight")?

Choose the exception type

Select one choice, then check.

HintIdentify the failed operation

int() receives a string, but the characters do not form an integer.

SolutionConversion raises ValueError

int("eight") raises ValueError. The string type is accepted by int(), but this particular string cannot be interpreted as an integer.

Exercise: Handle invalid integer text

Edit the program so invalid text prints score must be a whole number instead of stopping with a traceback.

Catch the expected ValueError

Ready to run.

HintWrap only the conversion

Put score = int(text) in a try block and print the message from except ValueError.

SolutionCatch the conversion failure

Write:

Invalid text selects the handler. Valid integer text reaches the else block and prints the converted score.

Exercise: Keep the try block narrow

Which structure makes it clearest that only conversion is expected to fail?

Choose the structure

Select one choice, then check.

HintMatch handler to operation

The handler should cover only the statement known to raise ValueError.

SolutionSeparate conversion from later work

Put int(text) in try, handle ValueError, and place dependent computation in else. Unrelated errors then remain visible.

Exercise: Do not hide a typo

What is the best response to this failure?

Choose the response

Select one choice, then check.

HintExpected or mistaken?

Ask whether a correctly written program should normally encounter this failure.

SolutionFix the programming error

The program intended to print total. Correcting the spelling removes the cause. Catching NameError would hide the typo.

Exercise: Handle two expected failures

What does this program print?

Choose the output

Select one choice, then check.

HintTrace the expression in two steps

First evaluate scores["Ada"], then pass that result to int().

SolutionValueError selects the invalid handler

Lookup succeeds and returns "nine". Converting that text raises ValueError, so Python prints invalid.

Catch Only What You Can Resolve

When considering try and except:

  1. identify the exact operation that may fail;
  2. name the specific expected exception;
  3. keep unrelated work outside the try block;
  4. provide a meaningful response or result;
  5. leave unexpected programming errors visible.

The next lesson uses assertions for a different purpose: exposing assumptions that should remain true when the program itself is correct.