This is an archived version of the course and is no longer updated. Please find the latest version of the course on the main webpage.

Exception handling

Now that you’ve watched the video, we will go into a bit more detail about how to implement Exception handling in Python.

In the remainder of this module, there will not be any formal exercises. Instead, I want you to just try things out as we go along. Try making sure you understand the execution flow. For example, where does the code move to when an exception occurs? Where does it go when there are no exceptions? If you are not sure, write some code with deliberate errors (e.g. x=5/0, x = dict["non-key"]) to test it out yourself.

As a summary, when an Exception occurs, you have three choices:

  1. Don’t do anything. Let the Python runtime interpreter handle the Exception (mainly what you have been doing so far)
  2. Handle the exception yourself
  3. Raise a new exception

In its simplest form, when you expect a piece of code to raise an exception, you enclose it in a try block.

And you deal with any exceptions in the except block.

try:
    # Any code that may raise an Exception goes here.
except:
    # Handle Exceptions here 

You can target specific classes of Exceptions to handle. Any other Exception classes will be left to the Python runtime interpreter to handle.

try:
    # Any code that may raise an Exception goes here.
except ValueError:
    # Handle ValueError here
except ZeroDivisionError:
    # Handle ZeroDivisionError here

You can also handle multiple classes of Exceptions together

try:
    # Any code that may raise an Exception goes here.
except (ValueError, ZeroDivisionError):
    # Code will end up here if ValueError or ZeroDivisionError is raised

You can also use a non-specific except as a “catch-all” to handle any other classes of Exceptions. Please use this with caution though! It is better to use specific exceptions to make it easier to maintain your code in the future.

try:
    # Any code that may raise an Exception goes here.
except ValueError:
    # Handle ValueError here
except ZeroDivisionError:
    # Handle ZeroDivisionError here
except:
    # Handle any other errors here

If no Exceptions were raised, the code in the else block will be subsequently executed:

try:
    # Any code that may raise an Exception goes here.
except:
    # Execution will flow to here if an Exception occurs
else:
    # This will execute when no Exception has occurred

Include any “cleanup” code in a finally block, which will be executed whether or not an Exception occurred.

try:
    # Any code that may raise an Exception goes here.
except:
    # This will be executed when an Exception occurs
finally:
    # This will be executed after execution reaches either the end of the try block or the except block

Finally, you can force an error if you manually raise an Exception (you can include a custom message). Try the following in an interpreter for yourself!

>>> raise ValueError    ## shorthand for ValueError()
>>> raise ValueError()  ## raise error without any messages
>>> raise ValueError("I am an error! Be very afraid!")  # raise an error with a custom message

You can also do the following if you want to print an error message and then re-raise the Exception

try:
    raise NameError("A name error. Woohoo!")
except NameError:
    print("I do not want to deal with this! Python, I'll leave this to you!")
    raise