How to use try except for Python exception handling

Learn how to use try, except, else, and finally (or try catch) for Python exception handling to improve program flow control.

How to use try except for Python exception handling
Picture by Alleksana, Pexels.
10 minutes to read

Exceptions are events that can modify the flow of control through a Python application and are triggered when errors occur. When writing production code it’s a good idea to both intercept or “catch” exceptions and to throw or “raise” exceptions so you can make your application stop, warn the user, or perform another action if something goes wrong.

In Python, exception handling is achieved using try except blocks, which are akin to the try catch blocks of other languages, such as PHP. As the name suggests, the try part attempts to run a block of code, while the except block returns an exception if it fails.

In this project, I’ll show you the basics of using try/except to catch Python exceptions and modify the flow of control in your applications when things go wrong. There’s quite a bit more you can do with Python exception handling, but this is plenty to get you started.

Why catch exceptions?

Firstly, let’s take a look at what happens when you don’t catch an exception in your Python program. In the below example, we’ll attempt to use the open() function to open a file called exists.txt which exists on my local machine. If it works, the code runs and no exception is returned and no error is displayed.

file = open('exists.txt')

If we repeat that process by attempting to run open() on a file called missing.txt that does not exist, Python will throw or “raise” an exception. As we’re not doing anything to catch this exception, it’s known as an uncaught exception.

Uncaught exceptions, while not an issue in a Jupyter notebook where you can fix the issue manually, can be problematic in production code and would cause execution to stop completely, effectively crashing the application.

That said, exceptions are very useful to programmers, since they return a “traceback”. The traceback tells you why the program failed and what specific type of exception was raised or thrown. In this example, it tells us that the issue lies with the line file = open('missing.txt') which throws a FileNotFoundError because no such file or directory exists.

file = open('missing.txt')
FileNotFoundErrorTraceback (most recent call last)

<ipython-input-2-3e55dded282a> in <module>
----> 1 file = open('missing.txt')


FileNotFoundError: [Errno 2] No such file or directory: 'missing.txt'

The try except block

A try/except block wraps up the call to the open() command in a try statement. Python will try to run the code and, if it works, the contents of the file will be stored in the file variable and File exists will be printed. If it fails, except will run and raise an Exception which prints File does not exist.

try:
    file = open('exists.txt')
    print('File exists')
except Exception:
    print('File does not exist')
File exists
try:
    file = open('missing.txt')
    print('File exists')
except Exception:
    print('File does not exist')
File does not exist

Specifying the exception type

As we saw in the first example, running open() on a file that does not exist actually returns a FileNotFoundError. By adding an additional except block to catch the FileNotFoundError we can display a more informative error to the user to explain that the code failed because the file does not exist.

Importantly, the bare Exception at the end needs to follow any more specific exceptions above, otherwise it will simply say An error occurred rather than show the more specific and useful error message.

There are a wide number of common Python exception types that you can incorporate into your code to catch specific exceptions by their type and then change the program flow accordingly, or show more useful error messages. In addition to these common exception types, many Python applications raise their own more specific exceptions that you may wish to incorporate into your code.

try:
    file = open('exists.txt')
    print('File exists')
except FileNotFoundError:
    print('File does not exist')
except Exception:
    print('An error occurred')
File exists
try:
    file = open('missing.txt')
    print('File exists')
except FileNotFoundError:
    print('File does not exist')
except Exception:
    print('An error occurred')
File does not exist

Catching specific exception information

Another neat trick to making your exception messages more informative is to catch the exception message thrown and output that. For example, instead of using except FileNotFoundError: print('File does not exist'), we can use except FileNotFoundError as e: print('File does not exist:', e). If you run the code below, you’ll see that this prints a more informative exception stating: File does not exist: [Errno 2] No such file or directory: 'missing.txt'.

try:
    file = open('exists.txt')
    print('File exists')
except FileNotFoundError as e:
    print('File does not exist:', e)
except Exception as e:
    print('An error occurred:', e)
File exists
try:
    file = open('missing.txt')
    print('File exists')
except FileNotFoundError as e:
    print('File does not exist:', e)
except Exception as e:
    print('An error occurred:', e)
File does not exist: [Errno 2] No such file or directory: 'missing.txt'

Using else in a try except block

The else statement can also be added to a try/except block to aid flow control. In the code example below, we try and run open() and throw a FileNotFoundError if it fails to find the file, and a general Exception if something else goes wrong. If the file opens correctly, the else statement will kick in and the file contents will be read and printed out.

try:
    file = open('exists.txt')
    print('File exists')
except FileNotFoundError as e:
    print('File does not exist:', e)
except Exception as e:
    print('An error occurred:', e)
else:
    print(file.read())
    file.close()
File exists
Here are the file contents.
try:
    file = open('mising.txt')
    print('File exists')
except FileNotFoundError as e:
    print('File does not exist:', e)
except Exception as e:
    print('An error occurred:', e)
else:
    print(file.read())
    file.close()
File does not exist: [Errno 2] No such file or directory: 'mising.txt'

Using finally in a try except block

The finally statement is also a useful addition to the try/except block. Unlike else, which only runs if no exception is thrown, finally will run whether there’s an exception or not. Here’s a quick example showing it in action.

try:
    file = open('exists.txt')
    print('File exists')
except FileNotFoundError as e:
    print('File does not exist:', e)
except Exception as e:
    print('An error occurred:', e)
else:
    print(file.read())
    file.close()
finally:
    print('This bit always runs. Exception or not.')
File exists
Here are the file contents.
This bit always runs. Exception or not.
try:
    file = open('missing.txt')
    print('File exists')
except FileNotFoundError as e:
    print('File does not exist:', e)
except Exception as e:
    print('An error occurred:', e)
else:
    print(file.read())
    file.close()
finally:
    print('This bit always runs. Exception or not.')
File does not exist: [Errno 2] No such file or directory: 'missing.txt'
This bit always runs. Exception or not.

Matt Clarke, Friday, December 24, 2021

Matt Clarke Matt is an Ecommerce and Marketing Director who uses data science to help in his work. Matt has a Master's degree in Internet Retailing (plus two other Master's degrees in different fields) and specialises in the technical side of ecommerce and marketing.