Study guide

Exception Types, try, except, else, and finally

PCEP Certified Entry-Level Python Programmer Study Guide Exam

Track your progress as you read

Finished sections get a check mark.

1 PCEP Exam Map and Study Strategy

Current PCEP-30-02 Facts How PCEP Tests Code Reading Official Resources and Ethical Prep Four-Week Study Plan and Readiness

2 Computer Programming and Python Fundamentals

1.1 Lexis, Syntax, Semantics, and Indentation 1.2 Identifiers, Keywords, Comments, and Basic Program Structure 1.3 Literals, Types, and Numeral Systems 1.4 Operators, Precedence, and Type Conversion 1.5 print(), input(), and Console Tracing

3 Control Flow

Boolean Expressions, Comparisons, and Truthiness If, Elif, Else, and Decision Trees While Loops and Sentinel Patterns For, Range, and Iteration Patterns Break, Continue, Pass, Loop Else, and Nesting

4 Data Collections

Indexing, Slicing, and Sequence Rules Lists, Mutation, Methods, and Aliasing Tuples, Immutability, and Packing Dictionaries, Keys, Membership, and Iteration Strings, Sets, and Collection Choice

5 Functions and Exceptions

def, return, None, and Call Flow Parameters, Arguments, Defaults, and Keywords Scope, Shadowing, global, and Local Errors Exception Types, try, except, else, and finally Recursion, Debugging, and Final Code Reading

Exception Types, try, except, else, and finally

Key Takeaways Explain This Topic AI

A try block holds code that may raise; matching except clauses decide whether execution recovers.

Except clauses are tested top to bottom, so specific handlers must precede broad ones like Exception.

The else clause runs only when the try block completes with no exception raised.

The finally clause runs on every path (success, handled error, or unhandled error) and is used for cleanup.

Core PCEP exception types are NameError, TypeError, ValueError, IndexError, KeyError, and ZeroDivisionError.

Last updated: June 2026

What an exception changes

An exception interrupts the normal statement-by-statement flow. If code in a try block raises, Python abandons the rest of the try block and searches the attached except clauses from top to bottom. If a clause matches the exception's class, that handler runs. If none matches, the exception propagates outward and may crash the program. try:

  • n = int('8')
  • print(10 / n)

except ValueError:

print('bad number')

except ZeroDivisionError:

print('zero')

The conversion int('8') succeeds (n is 8), the division succeeds, and no exception is raised, so no handler runs. The snippet prints 1.25 . Note the key detail: once int('8') had failed, print(10 / n) would never have executed, because Python stops the try block at the first failing statement.

The six exception types PCEP expects

  • Exception Typical cause in exam snippets
  • NameError Reading a name that is not defined in any scope
  • TypeError Wrong operand type, or wrong function arguments
  • ValueError Right type, invalid value, e.g. int('abc')
  • IndexError List, tuple, or string index out of range
  • KeyError Missing dictionary key with bracket lookup
  • ZeroDivisionError Division or modulo by zero

The TypeError versus ValueError split is heavily tested. int(3.5) works because the type (float) is acceptable. int('abc') raises ValueError : strings are an acceptable type for int() in general, but that particular string cannot be parsed.

Collection errors follow the same logic. letters[9] raises IndexError because integer indexing is valid in general but position 9 does not exist. record['age'] raises KeyError because bracket key lookup is valid but that key is absent. Recognizing why the type is right but the value/position is wrong is what the exam rewards.

Handler order is significant

Except clauses are tested in the order written. A broad handler placed first catches the exception before any later, more specific handler gets a chance. try:

  • values = [1, 2]
  • print(values[5])

except Exception:

print('general')

except IndexError:

print('index')

This prints general , not index . Because IndexError is a subclass of Exception , the first matching clause wins and the specific clause is dead code. Correct ordering puts except IndexError before except Exception .

You can also catch several types in one clause with a tuple: try:

x = int('z')

except (ValueError, TypeError):

print('input problem')

The parentheses are required; except ValueError, TypeError: is invalid syntax in Python 3. This prints input problem because int('z') raises ValueError, which the tuple includes.

else, finally, and continuation

The else clause runs only if the try block completes with no exception. The finally clause runs on every path, used for cleanup like closing files. try:

item = {'a': 1}['b']

except KeyError:

print('missing')

else:

print('found')

finally:

print('done')

The lookup raises KeyError. The except prints missing , else is skipped (an exception occurred), and finally prints done .

When an exception is handled , execution resumes after the whole try statement: try:

print(int('x'))

except ValueError:

  • print('handled')
  • print('after')

The output is handled then after ; the inner print never completed because int('x') failed first. Exam routine: (1) find the first try statement that can fail, (2) name its exact exception class, (3) pick the first matching except, (4) decide whether else runs, (5) note what finally prints. This stops the two classic errors: running statements after the failing line, and choosing the most specific handler instead of the first matching one.

Capturing the exception object and the exception hierarchy

You can bind the raised exception to a name using as , which lets a snippet print the message: try:

print(10 / 0)

except ZeroDivisionError as e:

print('error:', e)

This prints something like error: division by zero . The name e exists only inside the except block; PCEP may ask whether e is available after the try statement (in Python 3 it is deleted when the block ends).

Built-in exceptions form a class hierarchy , and that ordering is exactly why broad handlers can swallow specific ones. A simplified view of the part PCEP tests: BaseException

  • └── Exception
  • ├── ArithmeticError
  • │ └── ZeroDivisionError
  • ├── LookupError
  • │ ├── IndexError
  • │ └── KeyError
  • ├── NameError
  • │ └── UnboundLocalError
  • ├── TypeError
  • └── ValueError

Two practical consequences appear on the exam. First, except LookupError: catches both IndexError and KeyError , because both are subclasses of LookupError . Second, except Exception: catches essentially every ordinary runtime error, which is why placing it first makes later specific clauses unreachable.

Raising your own exception. The raise keyword triggers an exception deliberately: raise ValueError('too big') . A bare raise inside an except block re-raises the current exception so an outer handler can see it. If a snippet raises inside an except clause and no outer handler catches it, the program crashes after any finally has run. Trace handler bodies as carefully as the original try block, since a second failure there changes the outcome.

A final reusable rule: a finally block runs even when the try block contains a return . The finally executes first, and if finally itself contains a return , that value overrides the one from the try block, a subtle item that occasionally appears in scenario questions. When in doubt, remember finally always gets the last word before control leaves the try statement.