Python Error Handling

Handle your errors in Python like a pro

Python Error Handling
Error handling in Python, image by the author

When during the execution of a program, Python encounters an error, it stops. This can be caused by two types of errors, syntax errors, or exceptions. In this article, we will discuss the second, exceptions, and show how to handle, catch, and raise them.

What are Exceptions?

Exceptions are errors that Python reports when syntactically correct code executes, and an exceptional situation occurs. For example, look at the following code.

This program tries to divide the number ten by zero, which is something that is not possible in Python.

When you execute this program, Python raises a ZeroDivisionError and terminates the application.

> python3 main.py
Traceback (most recent call last):
File “main.py”, line 3, in <module>
result = number / divider
ZeroDivisionError: division by zero

This ZeroDivisionError is an Exception. Each Exception is a Python class derived from a common base class. In this case, from BaseException.

Python has many built-in exceptions. For example, AssertionError, AttributeError, EOFError, FloatingPointError, ImportError, ModuleNotFoundError, IndexError, MemoryError, and NotImplementedError.

These are all documented in the excellent Python documentation.

How can we handle Exceptions?

As we saw previously, if an exception occurs and don’t handle it, Python will report the error and terminate your application.

Usually, this is not what you want. To prevent this, you can handle a possible exception by enclosing your statements inside a try-except statement.

This try-except statement works as follows. First, Python executes the statements between try and except. These statements are called the try clause.

If no exception occurs, the statements below except are skipped and the execution of the try statement is finished. The statements below except are called the except clause.

But, if an exception occurs during the execution of the try clause, the rest of the statements are skipped. Then if the type matches the exception named after the except statement, this except clause is executed. The execution continues after the try statement.

Handling multiple exceptions

It is possible to create multiple except clauses for a single try clause to handle multiple specific exceptions. This gives you more control over the statements that you want to execute when a specific exception occurs.

In this example, we handle a ZeroDivisionError and a ValueError. The ValueError occurs when the user doesn’t enter a number, the ZeroDivisionError occurs when the user enters a zero.

Here we print a message, but you can imagine that depending on the type of exception you could execute different statements.

General exception handler

It is also possible to add another except clause to catch a general exception. This way you create a safety net that catches all other exceptions.

If an exception occurs other than a ZeroDivisionError or ValueError, the general except-clause on row nine is triggered. This way you make sure that all exceptions are handled.

The order of the except clauses is important, always start with the most specific exception. If we would start with general except-clause, the specific ones would never be executed.

Use Try Finally

The finally block lets you execute code, regardless of the result of the try- and except blocks. This can sometimes be useful. For example, when working with files.

In this example, the finally block closes the file. Even if an exception occurs, the finally block gets executed and closes the file.

With statement

Pythons with statement can be used to simplify code that uses try-finally. Let’s look at how we can rewrite the previous example using with.

By using with when opening a file, you make sure that when the with block is finished the file automatically gets closed. The result is the same as with using finally but it looks a bit cleaner.

Raising your own exceptions

Before we talked about handling exceptions that were raised by standard Python modules. It is also possible to raise an exception from your code.

Now, why would you want to raise an exception?

Say that you develop a Python module that needs a certain configuration file to function correctly. You could raise an exception when you cannot find the configuration file.

In this case, we raise the FileNotFoundError exception which is part of the standard Python modules. We could also define our own exception class and raise that exception.

Define custom exception class

To be able to raise a custom exception, we need to define a class that derives from Exception. In the ConfigureError init we call the init of the superclass.

Logging and raising exceptions

Another reason to raise an exception is for logging. You catch the exception, log the error message, and reraise the exception.

In this case, make sure that you call raise without any arguments. This will make sure that the call stack information stays intact.

Conclusion

In this article, we saw what exceptions are and how you can handle them. We used try-finally and with to define clean up actions. Finally, we saw how to raise custom exceptions.

With this information, you should be able to handle all your Python errors.

Thank you for reading!