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:
| Exception | Usually means |
|---|---|
ValueError | right type, unacceptable value: int("ten") |
TypeError | wrong type for the operation: "5" + 5 |
KeyError | dictionary key not found |
IndexError | list position out of range |
AttributeError | object has no such attribute: None.upper() |
NameError | variable name not defined |
FileNotFoundError | path doesn't exist |
ZeroDivisionError | division 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:
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":
prices = {"stalls": 45}
prices["balcony"] # KeyError: 'balcony'
seats = ["A1", "A2"]
seats[5] # IndexError: list index out of rangeA 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:
| Exception | Cause |
|---|---|
FileNotFoundError | path doesn't exist |
FileExistsError | creating something that exists (mode "x", mkdir) |
PermissionError | not allowed to read, write or delete |
IsADirectoryError | opened a folder as if it were a file |
TimeoutError, ConnectionError | network problems |
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:
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.
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.
Exception Types Reference in a small program
rows = ["12", "unknown", "8"]
for text in rows:
try:
count = int(text)
except ValueError:
print("Invalid quantity:", text)
else:
print("Accepted:", count)Accepted: 12
Invalid quantity: unknown
Accepted: 8Line-by-line explanation
- Lines 3 to 4Only the conversion is inside
try, so only conversion errors are handled. - Lines 5 to 6
ValueErroris the specific exception for unconvertible text. - Lines 7 to 8
elseruns when the conversion succeeded.
Classifying import failures
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))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 TrueLine-by-line explanation
- Lines 15 to 16One
KeyErrorhandler covers both a missing field and an unknown section; the message shows which key. - Lines 17 to 18The bad quantity is a
ValueError, reported separately. - Line 22
issubclass()confirms the hierarchy shown above.
Common Exception Types Reference Mistakes
Catching Exception around everything
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?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
try:
open("sales.csv")
except OSError:
print("Some file problem")
except FileNotFoundError:
print("Missing file") # never reachedtry:
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.
Which exception normally describes invalid integer text?
Which review concern is valid for exception types reference?
Exception Types Reference Quiz
2 questions to check what you learned.
Which exception normally describes invalid integer text?
- KeyError
- ValueError
- Python ignores the distinction
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