Common Built-in Exceptions
| Since: | Python 2(2000) |
|---|
Python provides many built-in exception classes. Knowing the types of errors helps you write appropriate except blocks. In except blocks, always specify a concrete exception class — avoid catching everything with a bare except or except Exception as a general rule.
Common Built-in Exceptions
| Exception Class | When It Occurs |
|---|---|
| ValueError | The type is correct but the value is invalid (e.g., int('abc')). |
| TypeError | An operation is applied to a value of an inappropriate type (e.g., 'text' + 1). |
| KeyError | A dictionary is accessed with a key that does not exist. |
| IndexError | A list is accessed with an index that is out of range. |
| AttributeError | An attribute or method that does not exist on the object is accessed. |
| FileNotFoundError | An attempt is made to open a file that does not exist. |
| ZeroDivisionError | An attempt is made to divide by zero. |
| NameError | An undefined variable is referenced. |
| ImportError | A module import fails. |
| StopIteration | An iterator runs out of items (normally handled automatically). |
| RecursionError | The maximum recursion depth is exceeded. |
| MemoryError | The program runs out of memory. |
| OverflowError | The result of a numeric operation is too large (floats only; ints have arbitrary precision). |
| NotImplementedError | Raised intentionally when a method that a subclass should implement has not been implemented. |
Sample Code
builtin_exceptions.py
try:
n = int('abc')
except ValueError as e:
print(f"ValueError: {e}") # invalid literal for int() with base 10: 'abc'
# TypeError: incorrect type
try:
result = 'Age: ' + 25
except TypeError as e:
print(f"TypeError: {e}") # can only concatenate str (not "int") to str
# KeyError: key not found in dictionary
user = {'name': 'Gojo Satoru', 'age': 28}
try:
email = user['email']
except KeyError as e:
print(f"KeyError: {e}") # KeyError: 'email'
# IndexError: index out of range
members = ['Itadori Yuji', 'Fushiguro Megumi', 'Kugisaki Nobara']
try:
print(members[10])
except IndexError as e:
print(f"IndexError: {e}") # list index out of range
# AttributeError: attribute does not exist
try:
'hello'.upper_case() # upper_case() does not exist
except AttributeError as e:
print(f"AttributeError: {e}")
# FileNotFoundError: file does not exist
try:
with open('nonexistent_file.txt') as f:
content = f.read()
except FileNotFoundError as e:
print(f"File not found: {e.filename}")
# ZeroDivisionError: division by zero
try:
result = 100 / 0
except ZeroDivisionError:
print("Cannot divide by zero")
# Check exception inheritance
print(issubclass(FileNotFoundError, OSError)) # True
print(issubclass(ZeroDivisionError, ArithmeticError)) # True
print(issubclass(ValueError, Exception)) # True
# Inspect the exception object
try:
x = int('abc')
except ValueError as e:
print(type(e).__name__) # ValueError
print(str(e)) # error message
print(e.args) # tuple of error arguments
Running the code produces the following output:
python3 builtin_exceptions.py
ValueError: invalid literal for int() with base 10: 'abc'
TypeError: can only concatenate str (not "int") to str
KeyError: 'email'
IndexError: list index out of range
AttributeError: 'str' object has no attribute 'upper_case'
File not found: nonexistent_file.txt
Cannot divide by zero
True
True
True
ValueError
invalid literal for int() with base 10: 'abc'
("invalid literal for int() with base 10: 'abc'",)
Common Mistakes
Common Mistake 1: Catching the base Exception class
Catching all exceptions with the base Exception class can hide unintended errors. Specify a concrete exception class whenever possible.
try:
data = {'name': 'Gojo Satoru', 'power': 9999}
result = data['level'] # KeyError
except Exception:
pass # silently swallows the error
The same logic can also be written as:
try:
data = {'name': 'Gojo Satoru', 'power': 9999}
result = data['level']
except KeyError as e:
print(f'Key not found: {e}')
except TypeError as e:
print(f'Type error: {e}')
Common Mistake 2: Forgetting to re-raise in an except block
Logging an exception without propagating it upward can cause silent failures. Unless you intentionally want to suppress the error, use raise to re-raise it.
import logging
# Exception is logged but not propagated (None is returned silently)
def get_curse_level(name):
try:
levels = {'Itadori Yuji': 1, 'Fushiguro Megumi': 2}
return levels[name]
except KeyError:
logging.error(f'{name} not found')
# no raise — returns None silently
The same logic can also be written as:
import logging
# Re-raise the exception when needed
def get_curse_level_ok(name):
try:
levels = {'Itadori Yuji': 1, 'Fushiguro Megumi': 2}
return levels[name]
except KeyError:
logging.error(f'{name} not found')
raise # re-raises the original exception
Common Mistake 3: Using a bare except
A bare except: (without an exception class) also catches KeyboardInterrupt and SystemExit, which can prevent the program from being stopped with Ctrl+C.
try:
long_process()
except: # also catches KeyboardInterrupt
pass
The same logic can also be written as:
try:
long_process()
except Exception: # does not catch system-level exceptions
pass
Overview
Python's exception classes are organized in a hierarchy. At the top is BaseException, with Exception (for regular program errors), KeyboardInterrupt, SystemExit, and others beneath it. In typical error handling, you deal with subclasses of Exception.
Understanding the exception class hierarchy lets you catch errors at the right level of granularity. For example, FileNotFoundError is a subclass of OSError, so you could catch it with except OSError — but specifying FileNotFoundError directly makes your intent clearer.
Silently ignoring an exception with a bare except and pass can make bugs hard to find. At a minimum, add a log statement or print to record that an error occurred.
If you find any errors or copyright issues, please contact us.