Common Python exceptions#
Python has dozens of specific errors that can be raised when code fails to run. Below are a few common ones that you may encounter in Activity 3.
TypeError#
Occurs when an operation is applied to an object of an inappropriate type.
# Example: Trying to add a number and a string
1 + 'string'  # This will raise a TypeError
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[1], line 2
      1 # Example: Trying to add a number and a string
----> 2 1 + 'string'  # This will raise a TypeError
TypeError: unsupported operand type(s) for +: 'int' and 'str'
ValueError#
- Raised when a function receives an argument of the right type but an invalid value. 
- Example: - int('abc')(trying to convert an invalid string to an integer).
int("abc")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[2], line 1
----> 1 int("abc")
ValueError: invalid literal for int() with base 10: 'abc'
KeyError#
- Raised when a dictionary key is not found. 
- Example: - my_dict['nonexistent_key'](trying to access a key that doesn’t exist in the dictionary).
# Example: Accessing a nonexistent key in a dictionary
my_dict = {"a": 1, "b": 2}
my_dict['nonexistent_key']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Cell In[3], line 3
      1 # Example: Accessing a nonexistent key in a dictionary
      2 my_dict = {"a": 1, "b": 2}
----> 3 my_dict['nonexistent_key']
KeyError: 'nonexistent_key'
IndexError#
- Raised when an invalid index is used to access a list or tuple. 
- Example: - my_list[10](trying to access the 11th element of a list with fewer elements).
my_list = [1, 2, 3]
my_list[10] 
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[4], line 2
      1 my_list = [1, 2, 3]
----> 2 my_list[10] 
IndexError: list index out of range
AttributeError#
Raised when an object does not have a specific attribute or method.
my_string = "Hello"
my_string.nonexistent_method()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[5], line 2
      1 my_string = "Hello"
----> 2 my_string.nonexistent_method()
AttributeError: 'str' object has no attribute 'nonexistent_method'
FileNotFoundError#
A FileNotFoundError occurs in Python when the code attempts to open or access a file that does not exist at the specified path.
with open("data/nonexistent_file.json", "r") as file:
    data = file.read()
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
Cell In[6], line 1
----> 1 with open("data/nonexistent_file.json", "r") as file:
      2     data = file.read()
File ~/work/lessons/lessons/.nox/docs-test/lib/python3.11/site-packages/IPython/core/interactiveshell.py:343, in _modified_open(file, *args, **kwargs)
    336 if file in {0, 1, 2}:
    337     raise ValueError(
    338         f"IPython won't let you open fd={file} by default "
    339         "as it is likely to crash IPython. If you know what you are doing, "
    340         "you can use builtins' open."
    341     )
--> 343 return io_open(file, *args, **kwargs)
FileNotFoundError: [Errno 2] No such file or directory: 'data/nonexistent_file.json'
By catching this exception, you can
- Raise a kinder and more informative message. 
- Direct the user toward the next steps 
- FUTURE: write tests for this step of the workflow (if you are creating a package!) that make sure that it handles a bad file path properly. 
from pathlib import Path
file_path = Path("data") / "nonexistent_file.json"
try:
    with open(file_path, "r") as file:
        data = file.read()
except FileNotFoundError as fe:
    raise FileNotFoundError(f"Oops! it looks like you provided a path to a file that doesn't exist. You provided: {file_path}. Make sure the file path exists. ")
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
Cell In[7], line 5
      4 try:
----> 5     with open(file_path, "r") as file:
      6         data = file.read()
File ~/work/lessons/lessons/.nox/docs-test/lib/python3.11/site-packages/IPython/core/interactiveshell.py:343, in _modified_open(file, *args, **kwargs)
    337     raise ValueError(
    338         f"IPython won't let you open fd={file} by default "
    339         "as it is likely to crash IPython. If you know what you are doing, "
    340         "you can use builtins' open."
    341     )
--> 343 return io_open(file, *args, **kwargs)
FileNotFoundError: [Errno 2] No such file or directory: 'data/nonexistent_file.json'
During handling of the above exception, another exception occurred:
FileNotFoundError                         Traceback (most recent call last)
Cell In[7], line 8
      6         data = file.read()
      7 except FileNotFoundError as fe:
----> 8     raise FileNotFoundError(f"Oops! it looks like you provided a path to a file that doesn't exist. You provided: {file_path}. Make sure the file path exists. ")
FileNotFoundError: Oops! it looks like you provided a path to a file that doesn't exist. You provided: data/nonexistent_file.json. Make sure the file path exists. 
If you don’t raise the error but instead provide a print statement, you can provide a simple, clean output without the full “stack” or set of Python messages that provides the full “tracking” or traceback of where the error originated.
The challenge with not raising a FileNotFound error is that it will be a bit trickier to test the output.
file_path = Path("data") / "nonexistent_file.json"
try:
    with open(file_path, "r") as file:
        data = file.read()
except FileNotFoundError as fe:
    print(f"Oops! it looks like you provided a path to a file that doesn't exist. You provided: {file_path}. Make sure the file path exists. ")
Oops! it looks like you provided a path to a file that doesn't exist. You provided: data/nonexistent_file.json. Make sure the file path exists. 
 
    