Common Types of Errors in Python and How to Handle Them

Praise James
11 min readJun 26, 2024

--

Photo by Author

Imagine you’re working on a cool project in Python, and you’ve written some code to create, for example, a love calculator. But when you try to run the code, the interpreter says, "Oops, there’s an error!" It’s telling you that something in your code that it doesn’t understand.

Don’t panic; making mistakes and getting errors is totally normal when learning to code in Python. It’s like solving a puzzle — you learn from figuring out what pieces don’t match and retrying.

This article will teach you about some common Python errors you might encounter when running your code and how to handle them.

Types of Errors and Exceptions in Python

Photo by Author

An error in Python is like a signal from your computer that something in your code doesn’t fit the rules of the Python language. It’s a way for the computer to say, "Hey, I don’t understand this part!"

Now, errors and exceptions are sometimes used interchangeably; however, there’s a slight difference between both terms.

Errors are like roadblocks that stop your program from executing, while exceptions are like detours that change the normal flow of the program and returns unexpected result.

Below are some common errors and exceptions in Python with code examples to help you recognize and understand them:

SyntaxError

This error occurs when the code violates Python’s syntax rules. It’s like making spelling or grammar mistakes in English language. Some common reasons for SyntaxError include misspelling a keyword or identifier, missing quotes, open parenthesis, and mismatched or missing punctuation.

Here is an example of code that can lead to SyntaxError in Python:

#mismatched or missing punctuation
if x = 5:
print('x equals 5')

Output:

This code resulted in a SyntaxError because we used an assignment operator instead of a comparison operator.

NameError

A NameError in Python occurs when you attempt to use or access a variable, function, or module name that has not been defined yet or is out of scope.

Here’s an example that can lead to a NameError:

#Using a variable that has not been defined
print(x)

Output:

Since ‘x’ has not been defined, this code will raise a NameError.

IndentationError

An IndentationError occurs when the spaces at the beginning of a code line do not follow expected patterns.

Here is an example to illustrate this error:

if 5 > 2:
print("Five is greater than two!")

Output:

In this example, there’s no proper indentation after the “if" statement, which would result in an IndentationError.

TypeError

A TypeError occurs when an operation is performed or a function is applied on an object of an inappropriate type. An example is when you try to add a string and an integer as shown below:

num = 5
text = "Hello"
result = num + text

Output:

In this example, the addition operation is performed on an integer and a string, which would result in a TypeError.

Type errors can also occur when you try to perform operations on objects that do not support the specific operation being attempted, such as trying to call a non-callable object. Here’s an example to illustrate this:

numbers = [1,2,3]
result = numbers(0)

Output:

In the example above, ‘numbers’ object is not callable. So, the attempt to use ‘numbers’ as a function instead of an indexable list would result in a type error.

ValueError

In Python, a ValueError is raised when a built-in operation or function receives an argument that has the right type but an inappropriate value.

You can get a ValueError in various scenarios, such as when you are try to convert a string to an integer, access an index that doesn’t exist in a list, or perform operations with inappropriate values for a specific function or operation.

Here is an example to illustrate this:

number = int("abc")

Output:

In this example, the ‘int()’ function is called with a string that cannot be converted to an integer, resulting in a ValueError.

KeyError

In Python, KeyError occurs when a program tries to access a key in a dictionary that doesn’t exist. So, if you attempt to retrieve a value using a key that is not present in the dictionary, you will get a KeyError. Here’s an example to illustrate this:

#Creating a dictionary
information = {'name': 'John', 'age': 25, 'city': 'New York'}

#Accessing a key that doesn't exist
value = information['gender']

Output:

In this example, trying to access the key ‘gender’ in the dictionary ‘information’ will result in a KeyError because ‘gender’ is not a valid key in the dictionary.

IndexError

This is another common error that occurs when you try to access an element in a list, tuple, or any other sequence using an invalid index. You will typically get this error when the index you provide is out of the valid range for that particular sequence as shown below:

numbers = [1, 2, 3, 4, 5]
print(numbers[5])
#This will raise an IndexError since the valid indices for 'numbers' are 0, 1, 2, 3, and 4.

Output:

This code attempts to access the element at index 5 in the list ‘numbers’, which is out of range. That’s why the code returned an IndexError. Remember that indexing in Python starts from 0.

ZeroDivisionError

In Mathematics, dividing by zero is undefined because we can’t share among zero people. Python agrees with Mathematics, that’s why it raises a ZeroDivisionError whenever you attempt to divide a number by zero.

Here’s an example of a Python code that will raise a ZeroDivisionError:

numerator = 15
denominator = 0
result = numerator / denominator

Output:

In this example, the division operation will raise a ZeroDivisionError since the denominator is zero.

FloatingPointError

Floating-point numbers or floats are used to represent real numbers with a decimal point. For example, 0.6, -3.345, and 2.5 are all floating-point numbers. These numbers are represented in computer hardware as base 2 (binary) fractions.

Now, here’s the thing: computers are good at working with whole numbers,but when it comes to dealing with numbers that have lots of decimal places, they can sometimes run into limitations.

Imagine trying to fit twelve cupcakes into your mouth at once – you might have to eat them one by one to make it fit. That’s kind of what happens with floating-point numbers in computers.

Because of this, when computers work with floating-point numbers, there might be small errors in the calculations, which can sometimes return unexpected results. That brings us to FloatingPointError.

A FloatingPointError in Python refers to the inaccuracies that can occur when working with the floating-point numbers, due to the limitations of computer hardware in representing these numbers with finite precision. This can lead to unexpected or inaccurate results in calculations. Here’s a code sample to demonstrate this error:

x = 1.1
y = 2.2
z = 3.3

if x + y == z:
print("x + y equals z")
else:
print("x + y does not equal z")

Output:

When you run this code, it prints "x + y does not equal z", even though mathematically 1.1 + 2.2 equals 3.3. This unexpected result occurs due to the limitations of floating-point representation in computers.

Note that computers do not explicitly notify you about floating-point errors like they do with others such as ZeroDivisionError and NameError. Instead, these errors can show through unexpected or inaccurate results. That’s why handling floating-point errors requires careful comparison of the returned results and the expected values.

UnboundLocalError

A local variable is created when a function starts its execution and it is only accessible within that specific function. Then, a local variable is lost when the function ends, and its scope is limited to the function in which it is defined.

Now, when this local variable is referenced before it’s assigned a value within the local scope of a function, it raises a UnboundLocalError. Here is a code example to illustrate this error:

def test():
print(var)
var = 10
test()

Output:

In this example, referencing the ‘var’ variable before its assignment within the ‘test’ function will result in an UnboundLocalError.

ImportError

In Python, an ImportError occurs when the import statement fails to import a module. This can happen due to various reasons such as the module not being installed, not being accessible from the current environment, or due to circular imports (when two or more modules depend on each other, creating a loop that confuses the Python interpreter). For example:

from math import funny_function

Output:

‘funny_function’ does not exist within the ‘math’ module, so when you try to import it, you will encounter an ImportError.

ModuleNotFoundError

When you encounter a ModuleNotFoundError in Python, it means that the import statement has failed to find the specified module.

ModuleNotFoundError is a subclass of ImportError. This means it specifically indicates that the module specified in the import statement can not be found, while ImportError is a more general exception that can be raised for various import-related issues. Here are some examples to demonstrate the ModuleNotFoundError exception:

import praise_module

Output:

In this example, ‘praise_module’ does not exist in the current environment, hence the ModuleNotFoundError.

import numpy

Output:

If NumPy is not installed in the current environment and you attempt to import it, a ModuleNotFoundError will occur.

FileNotFoundError

This error occurs when you attempt to open a non-existent file. Take a look at the example below:

file = open('pj_file.txt', 'r')
content = file.read()

Output:

In this example, the file ‘pj_file.txt’ does not exist, hence the error.

PermissionError

PermissionError, also known as [Errno 13], occurs when a file or directory cannot be accessed due to permission restrictions. So, if you don’t have the necessary permission to access or perform operations on a specific file, a PermissionError will be raised. It typically looks like this:

OverflowError

An OverflowError in Python happens when the result of an arithmetic operation is too large to be represented within the available memory or data type. Here’s an example that will lead to OverflowError:

import math
print(math.exp(1000))

This is what the output will look like:

In this example, the code tries to calculate the exponential function ‘e’ raised to the power of 1000 using the ‘math.exp()’ function from Python’s math module. But, the result of this calculation is too large to be represented within the range of numbers that Python’s arithmetic can handle. Hence, an OverflowError, specifically a "math range error," is raised, showing that the calculated result falls outside the representable range for the data type being used.

You can find a complete list of Python’s errors and exceptions in this official documentation.

How to Handle Exceptions in Python

Below are some ways to catch errors in Python before they halt the execution of your code.

Try-Except Statements

The try-except statement is the most common way to test your code for errors and handle the error.

Here’s how it works:
Try Block: The code that may raise an exception is placed inside the ‘try’ block.

Except Block: If an exception occurs in the ‘try’ block, the control immediately shifts to the ‘except’ block. The code inside the ‘except’ block is executed to handle the exception.

For example,

try:
file = open('pj_file.txt', 'r')
content = file.read()
file.close()
except:
print("Error: File Not Found")

Output:

In this example, the ‘try’ block attempts to open a file that doesn’t exist, which would raise a FileNotFoundError. The ‘except’ statement catches and handles the exception with an error message.

Note that if you use a bare ‘except’ statement like I did in the code above, it will catch any exception that occurs within the ‘try’ block, including both expected and unexpected exceptions.

This can make it difficult to identify and handle specific types of errors. That’s why you should consider this second method of handling exceptions.

Specifying the Exception

It is always good practice to mention specific exceptions whenever possible instead of using a bare ‘except’ clause. This allows for more targeted error handling and provides more control over how you manage different exceptions within the code.

Here’s how it works:
Try Block: The code that may raise an exception is placed inside the ‘try’ block.

Except Block: After the ‘try’ block, one or more ‘except’ blocks can be used to specify different exception types to handle. Each ‘except’ block is associated with a specific exception type, as shown below:

try:
file = open('pj_file.txt', 'r')
content = file.read()
file.close()

except FileNotFoundError:
print("Error: File not found")
except PermissionError:
print("Error: Permission denied")

Output:

In this example, the first ‘except’ block handles the FileNotFoundError exception. The second 'except' block handles the PermissionError exception.

Notice that when you run the code, it only returns the first error message. This is because, in Python, when an error is caught by an ‘except’ block, the program immediately jumps to the corresponding block and executes the code within it. This means that if the first ‘except’ block is triggered, the program will not proceed to the second ‘except’ block.

Using ‘finally’ Keyword

The ‘finally’ keyword is very helpful for maintaining code reliability and performing cleanup tasks like closing files or releasing resources.

In Python, the ‘finally’ block is used in conjunction with the ‘try-except’ statement to define a section of code that will always be executed, regardless of whether an exception is raised or not. Take a look at this example:

file = None #Intialize the file variable
try:
file = open('pj_file.txt', 'r')
content = file.read()
file.close()

except FileNotFoundError:
print("Error: File not found")
except PermissionError:
print("Error: Permission denied")

finally:
if file is not None:
file.close() # This will always be executed to ensure the file is closed

Output:

In this example, the ‘finally’ block ensures that the file is closed, even if an exception occurs while reading its contents.

Conclusion

As a Python programmer, errors and exceptions are part of the learning process. Your focus should be on understanding what went wrong and how to fix or handle it. This article should help you to anticipate these errors and write cleaner and more reliable code.

If you found this article helpful, connect with me on LinkedIn.

References:

Python Built-in Exceptions — w3schools

Built-in Exceptions Python 3.12.4 documentation — python.org

Python Exception Handling — Geeksforgeeks

Python Error Handling — w3schools

--

--

Praise James

Technical Content Writer and Storyteller | Python, Data Science | Using Analogies to Simplify Complex Topics to both Technical and Nontechnical Audiences.