Python Exception Types Reference

Recognise Python's common built-in exceptions, understand what causes each and catch the right one in the right place.

Lesson 53 of 107Intermediate12 min read

Python reports problems by raising an exception, and the exception's type tells you what kind of problem it is. Recognising the common types turns a traceback from a wall of red text into a precise diagnosis:

ExceptionUsually means
ValueErrorright type, unacceptable value: int("ten")
TypeErrorwrong type for the operation: "5" + 5
KeyErrordictionary key not found
IndexErrorlist position out of range
AttributeErrorobject has no such attribute: None.upper()
NameErrorvariable name not defined
FileNotFoundErrorpath doesn't exist
ZeroDivisionErrordivision by zero

This reference explains each family, how they're organised in the exception hierarchy, and how to catch exactly the ones you expect. It builds on the error handling lesson. The examples import ticket sales for a concert venue.

Value and type errors

These two are the most common and the most often confused:

Python
int("unknown")        # ValueError: invalid literal for int() with base 10: 'unknown'
"Tickets: " + 12      # TypeError: can only concatenate str (not "int") to str
len(42)               # TypeError: object of type 'int' has no len()

A ValueError means the function accepts that type, but not that particular value: int() accepts strings, but not this one. A TypeError means the operation doesn't support the type at all, or a function was called with the wrong number or kind of arguments.

The distinction suggests the fix. A ValueError usually comes from data, such as user input or a file, so validate it and report the bad record. A TypeError usually comes from code that combines the wrong things, so fix the code, often with a conversion or by correcting a function call. When you raise exceptions in your own functions, follow the same convention.

Lookup errors

KeyError and IndexError both inherit from LookupError and mean "the thing you asked for isn't there":

Python
prices = {"stalls": 45}
prices["balcony"]           # KeyError: 'balcony'
seats = ["A1", "A2"]
seats[5]                    # IndexError: list index out of range

A related one is AttributeError, raised for a missing attribute or method. The most common form is 'NoneType' object has no attribute ..., meaning a variable you expected to hold an object holds None, often because a function returned nothing.

Prevent lookups from failing where absence is normal: prices.get("balcony", 0), if index < len(seats), getattr(obj, "name", None). Where a missing key indicates a bug or bad data, let the exception happen, or catch it and raise a clearer one. Wrapping large blocks in except LookupError: can hide a real mistake in your data model, such as a misspelt key.

Filesystem errors

File and network operations raise subclasses of OSError, each describing a different external condition:

ExceptionCause
FileNotFoundErrorpath doesn't exist
FileExistsErrorcreating something that exists (mode "x", mkdir)
PermissionErrornot allowed to read, write or delete
IsADirectoryErroropened a folder as if it were a file
TimeoutError, ConnectionErrornetwork problems
Python
try:
    with open("sales.csv", encoding="utf-8") as file:
        rows = file.readlines()
except FileNotFoundError:
    print("sales.csv is missing: export it from the box office first")
except PermissionError:
    print("sales.csv is locked: close it in Excel and try again")

Different causes need different remedies, which is why catching the specific subclass is useful. Retrying can help with a timeout, but never with a missing file or a permission problem. except OSError as e: catches the whole family and e.errno and e.filename give details.

Exception scope

Every exception class inherits from BaseException. Ordinary errors inherit from its subclass Exception; a few special ones don't:

Text
BaseException
 ├── KeyboardInterrupt      (Ctrl+C)
 ├── SystemExit             (sys.exit())
 └── Exception
      ├── ValueError
      ├── TypeError
      ├── LookupError
      │    ├── KeyError
      │    └── IndexError
      ├── OSError
      │    ├── FileNotFoundError
      │    └── PermissionError
      └── ...

Catching a parent catches all its children, so except LookupError handles both KeyError and IndexError. Order except clauses from most specific to most general, because Python uses the first one that matches.

Catch the narrowest exception you expect, around the smallest piece of code that can raise it. except Exception: should be rare and should log the error; a bare except: or except BaseException: also swallows Ctrl+C and sys.exit(), making the program hard to stop.

Independent practice and a worked check

Task: classify ticket import failures and handle only the expected conversion and filesystem cases.

Python
from pathlib import Path

def read_quantities(path):
    try:
        lines = Path(path).read_text(encoding="utf-8").splitlines()
    except FileNotFoundError:
        print(f"{path} not found")
        return []
    quantities = []
    for line in lines:
        try:
            quantities.append(int(line))
        except ValueError:
            print(f"Skipping {line!r}")
    return quantities

Path("qty.txt").write_text("4\nfour\n6\n", encoding="utf-8")
print(read_quantities("qty.txt"))     # Skipping 'four', then [4, 6]
print(read_quantities("none.txt"))    # none.txt not found, then []
Path("qty.txt").unlink()

Each try wraps one kind of operation, so a bug elsewhere, such as a typo, still raises normally. For the worked check, the exception that normally describes invalid integer text is ValueError.

Reference and next practice

The documentation lists every built-in exception with the full hierarchy. Continue with debugging and logging. Practise with the Python exercises and Python quiz.

Exception Types Reference Summary

  • Value and type errors: ValueError indicates an unsuitable value while TypeError often indicates an unsupported operation or argument type.
  • Lookup errors: KeyError and IndexError report absent mapping keys and out of range sequence positions.
  • Filesystem errors: FileNotFoundError, PermissionError and other OSError subclasses describe external resource failures.
  • Exception scope: Catch the specific expected exception close to the operation that can raise it.

Exception Types Reference Examples

Each example shows the code, the output it produces and what each part does.

Example 1

Exception Types Reference in a small program

Python
rows = ["12", "unknown", "8"]
for text in rows:
    try:
        count = int(text)
    except ValueError:
        print("Invalid quantity:", text)
    else:
        print("Accepted:", count)
Output
Accepted: 12
Invalid quantity: unknown
Accepted: 8
Line-by-line explanation
  1. Lines 3 to 4Only the conversion is inside try, so only conversion errors are handled.
  2. Lines 5 to 6ValueError is the specific exception for unconvertible text.
  3. Lines 7 to 8else runs when the conversion succeeded.
Example 2

Classifying import failures

Python
records = [
    {"section": "stalls", "qty": "4"},
    {"section": "balcony", "qty": "two"},
    {"section": "boxes", "qty": "1"},
    {"qty": "3"},
]
prices = {"stalls": 45, "balcony": 30}

total = 0
for number, record in enumerate(records, start=1):
    try:
        section = record["section"]
        qty = int(record["qty"])
        price = prices[section]
    except KeyError as error:
        print(f"Record {number}: unknown or missing key {error}")
    except ValueError as error:
        print(f"Record {number}: bad quantity ({error})")
    else:
        total += qty * price
print("Total:", total)
print(issubclass(KeyError, LookupError), issubclass(FileNotFoundError, OSError))
Output
Record 2: bad quantity (invalid literal for int() with base 10: 'two')
Record 3: unknown or missing key 'boxes'
Record 4: unknown or missing key 'section'
Total: 180
True True
Line-by-line explanation
  1. Lines 15 to 16One KeyError handler covers both a missing field and an unknown section; the message shows which key.
  2. Lines 17 to 18The bad quantity is a ValueError, reported separately.
  3. Line 22issubclass() confirms the hierarchy shown above.

Common Exception Types Reference Mistakes

Catching Exception around everything

Don't
try:
    rows = load_sales()
    total = sum(r["qty"] * r["price"] for r in rows)
    send_report(total)
except Exception:
    print("Something went wrong")    # which step? what error?
Do
rows = load_sales()
try:
    total = sum(int(r["qty"]) * r["price"] for r in rows)
except (KeyError, ValueError) as error:
    print("Bad sales record:", error)
else:
    send_report(total)

Narrow the try to the risky step and catch the exceptions you can actually handle.

Putting the general handler first

Don't
try:
    open("sales.csv")
except OSError:
    print("Some file problem")
except FileNotFoundError:
    print("Missing file")        # never reached
Do
try:
    open("sales.csv")
except FileNotFoundError:
    print("Missing file")
except OSError:
    print("Some other file problem")

Exception Types Reference in Real Projects

Exception types in real systems

Well-designed libraries raise specific exception types so callers can react appropriately: requests raises Timeout and ConnectionError, json raises JSONDecodeError (a subclass of ValueError), and database drivers raise IntegrityError for duplicate keys. Applications often define their own hierarchy, such as class ImportError(AppError), so a top-level handler can catch everything the application itself raises without catching programming bugs.

Monitoring tools group crashes by exception type and location, so a spike in KeyError: 'section' after a supplier changes their export format is spotted quickly. Logging the exception type, message and traceback with logging.exception() is what makes that possible.

Exception Types Reference FAQ

What is the difference between ValueError and TypeError?

TypeError means an operation or function received a type it doesn't support, such as adding a string to an integer. ValueError means the type is acceptable but the value isn't, such as int("abc"). Fix type errors in code; validate data to prevent value errors.

What does 'NoneType' object has no attribute mean?

A variable you used as an object contains None. Common causes are a function that doesn't return anything, an in-place method whose result you assigned (items = items.sort()), or a lookup such as re.match() that found nothing.

How do I catch multiple exceptions in one except?

Put them in a tuple: except (KeyError, ValueError) as error:. Use separate except clauses when each type needs a different response.

What is the difference between Exception and BaseException?

BaseException is the root of all exceptions, including KeyboardInterrupt and SystemExit. Exception is the base for ordinary errors. Catch Exception (or narrower types) so that Ctrl+C and sys.exit() still work.

How do I find out what exception a line raises?

Run it and read the last line of the traceback, which names the exception type. The documentation for each function also lists what it raises, and type(error).__name__ inside an except Exception as error: block shows the type at run time.

Exception Types Reference Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Multiple choiceeasy

Which exception normally describes invalid integer text?

Multiple choicemedium

Which review concern is valid for exception types reference?

Exception Types Reference Quiz

2 questions to check what you learned.

  1. Which exception normally describes invalid integer text?

    • KeyError
    • ValueError
    • Python ignores the distinction
  2. Which statement correctly describes filesystem errors?

    • FileNotFoundError, PermissionError and other OSError subclasses describe external resource failures.
    • Only the example output matters, not the rule
    • Every operation has the same behavior