Skip to main content
Enchanted Code

Python 3 handling exceptions

tutorial, python

Intro

This tutorial is aimed to provide knowledge on how to handle exceptions (errors) in Python 3. It will assume you have an understanding of common Python functionality.

Requirements

  • Python 3 Knowledge, if not start here

What are they?

When making Python programs you may have encountered “unhandled exceptions”. Well in Python these are errors that have happened during runtime. Exceptions in Python are all instances of the BaseException class, this allows the programmer to write code to handle exceptions as well as create their own.

Handling Exceptions

First we will need to know how to handle exceptions. The example code that is shown below will create a divide by zero exception.

result = 2 / 0
print(result)

When this is run you will get a similar output to what is shown below.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

As you can see when we run this we do not get the output of the result. This is because when an exception is raised it will cause the program to crash. You may also notice that we get a error message, this “traceback” is telling us what line, file if we had multiple and the exception that was raised. This will come in handy when you have large amounts of code to quickly debug and find what code is causing your program to not work.

You could imagine that the example code is actually a user trying to enter a number into a calculator.

Try Except

Now we have an error lets see how to handle the exception so that the user will see a friendly error message.

try:
    result = 2 / 0
    print(result)
except ZeroDivisionError:
    print("You cannot divide by zero")

As you can see from the code we use “try” and “except” keywords. In the try block we place code that may raise an exception. Then in the “except” block we place code that will handle an exception. In our case the exception will be ZeroDivisionError.

There are many more built into Python, check them out at the Python docs

Now when this code is run we will get the following output:

You cannot divide by zero

If we were writing a program having a friendly error message is better than the program crashing. If we were asking for a users input we could display a message and then ask for the input again.

We could also omit the ZeroDivisionError. this will then catch all errors.

try:
    pass
except:
    pass

The “pass” keyword tells Python to skip execution of the current line.

We can also catch multiple using:

try:
    pass
except (ValueError, ZeroDivisionError):
    pass

If we wanted to run different code when different exceptions are raised we can use multiple “except blocks”.

try:
    pass
except ValueError:
    pass
except ZeroDivisionError:
    pass

Try Except Finally

Now lets add another feature of the try except clause. The “finally” keyword allows us to run code either after an exception or after a successful run of the try block.

try:
    pass
except:
    pass
finally:
    pass

Try Except Else Finally

Now lets use another feature. The “else” keyword allows us to run code when an exception has not been raised.

try:
    pass
except:
    pass
else:
    pass
finally:
    pass

Try Finally

We can also omit the the except block and just have a try and finally statement. This allows us to run code after an exception has occurred however not handle it. This could be used for example: closing access to a file.

try:
    pass
finally:
    pass

Raising Exceptions

Now lets raise an in-built exception in Python. We can do this using the “raise” keyword.

raise ValueError()
print("hello")

We could also give a message argument:

raise ValueError("my exception was raised!")
print("hello")

Custom Exception

When we want to create our own exception we can inherit from the Exception which is built-in. We can also inherit from existing exceptions like ValueError. It is not recommended to inherit from BaseException by the official Python documentation.

class MyException(Exception):
    pass

raise MyException()

“Safe” Calculator

Now lets put our knowledge to use. We are going to build the calculator we built in previous tutorials, however this time we are going to handle possible errors.

  1. Get two numbers from the user as separate variables
  2. convert both to int data-types
    • handle ValueError
  3. divide numbers together
    • handle ZeroDivisionError
  4. output the answer

Try to code your own version before looking at the completed code below.

try:
    num_a = int(input("Enter Number A? "))
    num_b = int(input("Enter Number B? "))

    result = num_a / num_b

    print(result)

except ValueError:
    print("Please enter valid integers")

except ZeroDivisionError:
    print("Cannot divide by zero")

Now lets test our application. We will first test it with a invalid integer.

We should see the following output when run:

Enter Number A? hello
Please enter valid integers

Lets test dividing by zero. We should get the following output:

Enter Number A? 2
Enter Number B? 0
Cannot divide by zero

As you can see our error messages work, they can handle entering invalid integers or prevent the user from dividing by zero.

Research

There are more features when handling exceptions that are not shown in this tutorial.

I would recommend researching re-raising errors with context using the “from” keyword. The code would look similar to what is shown below:

class MyError(Exception):
    pass

try:
    result = 5 / 0
except ZeroDivisionError as err:
    raise MyError() from err