Concepts / Understanding Python Errors and Tracebacks

Understanding Python Errors and Tracebacks

The try/except structure catches errors in risky code (like opening files) and runs recovery code in the except block instead of crashing.

  • Programming

When File Assumptions Fail

A program that opens a file makes an assumption: the file exists and can be read. That assumption may be wrong when a user enters a filename that does not exist or types something that is not a real filename. Without protection, the program crashes and the user sees a confusing traceback. Python's try/except structure lets the program anticipate this predictable failure and respond with a helpful message instead.

The central decision is simple: put code that might fail in try, then decide in except whether the program can recover or must stop.

The Try and Except Path

The try block contains risky code, such as an operation that opens a file. If every statement in the try block succeeds, Python skips the except block and continues with the code after the complete try/except structure. If the try block fails, Python immediately jumps to the except block. The except block can print a helpful message and then either allow the program to continue or terminate it.

inputsucceedsfailsjumps tohandles failureFilenameopen(filename)tryFile openedcontinue after try/exceptexcepthelpful messageRecovery choicecontinue or exitOpening error
What happens next when opening a file succeeds versus when it raises an error?

A Protected File Count

Suppose the program asks for a filename, opens that file, and counts lines beginning with Subject:. The file opening is the risky operation. The rest of the program depends on fhand being assigned a usable file object, so the program must decide what to do if opening the file fails.

fname = input("Enter the file name: ") try: fhand = open(fname) except: print("File cannot be opened:", fname) exit() count = 0 for line in fhand: if line.startswith("Subject:"): count = count + 1 print(count)

used byraiseshandled bymay callfnameuser inputopen(fname)risky operationOpening errorexceptmessage and decisionexit()program ends
How does an error move from the file operation to the matching except block?

Two Execution Traces

What do you think happens?

If the user enters mbox.txt and the file opens successfully, does the except block run?

  • Yes, every try/except runs both blocks
  • No, except is skipped when try succeeds
Reveal answer

Answer: No, except is skipped when try succeeds.

With a valid filename such as mbox.txt, the file opens, fhand is assigned, and execution continues to the counting loop and the final print statement.

Valid filename

Trace the program when the user enters mbox.txt and the file opens successfully.

Input: The user enters mbox.txt.

Try: open(fname) succeeds, and fhand is assigned.

Except: The except block is skipped because no failure occurred.

Counting: The program counts lines that start with Subject:.

Output: The program prints the count of subject lines.

Execution continues normally after the try/except structure.

Invalid filename

Trace the program when the user enters na na boo boo and the file cannot be opened.

Input: The user enters na na boo boo instead of a real filename.

Try: The open operation fails.

Jump: Python immediately jumps to the except block.

Message: The program prints the helpful error message written in except.

Exit: exit() terminates the program, so the counting loop and final print statement do not run.

The program handles the failure without showing the confusing traceback described in the unprotected case.

Recovery or Termination

Handling an error and ending a program are related but different actions. The except block is the recovery point: it can explain what went wrong and make a decision. Calling exit() is the termination choice. In the file-counting example, continuing is not useful after open fails because the remaining code depends on fhand being a valid file object. exit() stops the program immediately, before the loop and final print statement can run.

failshandled in exceptif program can proceedif continuation is impossibleOpening attemptbeforeOpening errorbeforeHelpful messageafterLater codeafter recoveryexit()after termination
How does program control flow differ after recovery code runs compared with after exit() terminates the program?

Mistakes with Error Handling

  • Putting the file operation outside try

    The risky operation is not protected, so a failure can occur before the except block can handle it.

    Fix: Place the open operation inside the try block.

  • Assuming except runs after every try block

    When try succeeds, Python skips except entirely.

    Fix: Put normal success-path work after the try/except structure.

  • Continuing to use fhand after opening failed

    The remaining program depends on fhand being a valid file object.

    Fix: Call exit() when the failed open makes it impossible to continue.

  • Giving the user no useful explanation

    The user does not understand what went wrong.

    Fix: Print a clear error message in the except block before deciding whether to continue or exit.

Practice the Control Flow

MEDIUM

Trace the protected file-counting program for two inputs: first mbox.txt when it opens successfully, and then na na boo boo when it cannot be opened. For each input, identify whether the except block runs, whether the counting loop runs, and whether the final print statement runs.

Hints
  • Start by deciding whether open(fname) succeeds.
  • A successful try skips except.
  • A failed try jumps to except; if that block calls exit(), later code does not run.
SituationExcept runs?Counting loop runs?Program outcome
File opens successfullyNoYesThe subject-line count is printed
File cannot be opened and except calls exit()YesNoA helpful message is printed and the program ends

Compare the two execution paths through the protected file operation.

Reliable File Failure Handling

Treat file opening as an operation that may fail, and protect it with try/except. In the except block, tell the user what went wrong. Then make an explicit control-flow decision: continue only if the rest of the program can work without the failed operation; otherwise call exit(). This produces a graceful failure instead of a crash followed by a confusing traceback.

Key Takeaways

  • Place risky file operations such as open() inside a try block.
  • If try succeeds, Python skips except and continues after the try/except structure.
  • If try fails, Python immediately jumps to except, where the program can print a helpful message.
  • Use exit() to terminate the program when the failed file operation makes continuation impossible.
  • Recovering from an error means handling it; terminating with exit() is one possible decision made during that handling.