Python Errors & Exception Handling Tutorial

In this tutorial we learn how to catch and handle errors with Python's built-in exception handlers, the try/except and try/finally blocks. We also cover how to raise error and warning exceptions.

Here's a table of contents of what you'll learn in this lesson:
(click on a link to skip to its section)

Let's jump right in.

What is an exception

When writing programs we will inevitably, and more often than not, encounter errors caused by not following proper syntax.

These errors are known as exceptions. The Python interpreter will raise an exception (stop the program and the report the error) when it encounters illegal operations.

Throughout the tutorial series we have seen various types of exceptions such as SyntaxError, KeyError, NameError, NotImplementedError etc. These exceptions help us track down, and repair the offending code.

List of built-in exceptions

The list of common Python exceptions, and their reasons, can be found at Python's official documentationOpens up in a new page .

How to handle exceptions

When exceptions are raised, they cause the current process to stop, and then pass the error to the calling process until the error is handled.

If the error is not handled, the application may crash.

How to catch exceptions with a try except block

We can use a try except block to handle an exception in Python.

The operation that may raise an exception is written inside the try clause. The code that handles the exception is written inside the except clause.

Syntax:
try:
	# code that may raise exception
except:
	# code to handle when error occured

Let’s consider a simple piece of illegal code that will raise a TypeError.

Example:
 print(1 + "Monty")

As we’ve already learned, we can’t add an integer and string together. It doesn’t make sense to the interpreter and it will raise a TypeError as a result.

We can handle this error easily with a try except block.

Example:
try:
    # erroring code
    print(1 + "Monty")
except:
    # error handling code
    print("Oops, can't int + string, it's illegal")

The example above is not very practical but demonstrates how to handle an exception.

How to catch specific exception types

We can evaluate code for specific error types and write handlers for each. A try except block may have any number of except clauses to deal with different exceptions.

Syntax:
try:
	# code that may raise exception
except error_type:
	# code that handles error_type errors
except:
	# catch-all other exceptions
Example:
try:
    print(1 + "Monty")
except TypeError:
    print("Oops, can't int + string, it's illegal")
except:
    print("Oops, an error occurred")

We can combine error types in a single except clause with a tuple. We simply write comma separated error types inside parentheses.

Syntax:
try:
	# code that may raise exception
except (error_type_1, error_type_2, ...):
	# code that handles multiple error_type errors
Example:
try:
    print(1 + "Monty")
except (TypeError, NameError):
    print("Oops, found a TypeError or NameError")
except:
    print("Oops, an error occurred")

How to use a try finally block

A try except block may have an optional finally clause. The finally clause will always be executed, and is generally used to release resources.

As an example let’s consider that we are manipulating a file on the system. Once we are done with the file, we need to do some cleanup, like saving and closing the file. These actions are done in the finally clause to guarantee their execution.

To use a finally clause we simply write the keyword finally and specify in its code block what we want to do.

Syntax:
try:
	# do something
finally:
	# do this thing no matter what

In the same directory as the .py file you are currently working on, create a txt file called test.txt and then run the example code.

Example:
try:
    f = open("test.txt", encoding = 'utf-8')
    # perform file ops
finally:
    if f.close:
        print("Cleanup complete.")

The example above will always close the test.txt file.

How to explicitly raise an exception

We can forcefully raise exceptions or warnings when errors or warnings occur in our code. Optionally, we can pass a value to the exception, or warning, between parentheses to clarify why the exception has been raised.

How to raise an error

To raise an error, we use the raise keyword along with the error type. If we want custom text, we can specify that text as a value between parentheses.

Syntax:
raise NameError

# or

raise NameError("Reason")
Example:
def is_odd_num(num):
    if not isinstance(num, int):
        raise TypeError("Value must be an integer")
    elif num % 2 == 0:
        print(num, "is an even number")
    else:
        print(num, "is an odd number")

is_odd_num("Monty")

In the example above we check if a number is odd or even. If the number is not an integer, we raise a TypeError with custom text.

How to raise a warning

To raise a warning, we use the raise keyword along with the warning type or just the word Warning. If we want custom text, we can specify that text as a value between parentheses.

Syntax:
raise Warning

# or

raise Warning("Reason")

# or

raise warning_type
Example:
 raise Warning("You have been warned!")

Summary: Points to remember

  • When illegal operations occur, the interpreter will raise an exception, indicating an error in our code.
  • To avoid application crashes, we should catch and handle our exceptions.
  • We can catch exceptions with a try block, and handle them in an except block.
  • In a try finally block, the finally clause will always be executed.
  • An error is raised with the raise keyword.