Exceptions

1. Introduction

A Python exception is 'raised' when the Python interpreter encounters an error. There are numerous types of exception, all are types of BaseException.

The raised exception is an object which contains details of the error and what code was being executed when the error was encountered.

2. Try-Except

If it is suspected that code might generate an exception, or if code raises an exception and analysis of this is to be done, then a try compound statement can be used with an 'except' clause. This tries to run the code in the try section and if specific exceptions are raised, then the code in the except clause is run.

Consider the following example:

# Catch an exception
import random
try:
    a = 1/random.random()
    # Random generates number in
    # range [0,1) so
    # ZeroDivisionError possible
except:
    a = 0
print("Done")

To reiterate, this will run the 'try' clause of the compound statement, and if an exception is raised in running that, then (and only then) will the 'except' clause run.

The 'except' clause in the example above catches any exception type. It is possible to be more specific and catch particular types of exception, for example, the following example will only run the except clause if the exception thrown is a 'ZeroDivisionError' type exception:

# Catch a specific exception:
import random
try:
    a = 1/random.random()
    # Random generates number in
    # range 0,1 so
    # ZeroDivisionError possible
except ZeroDivisionError:
    a = 0
print("Done")

There is a heirarchy of exception types.

If an exception is encountered and is not of the type handled by an except clause, it is raised to where the code that raised the exception was called from. This raising continues until there is exception handling or until the exception reaches the top level when the program exits and a stacktrace error message (which lists exception raising details) is printed.

More than one type of exception can be handled simultaneously in a couple of ways:

  1. The except clause can contain a tuple of types, for example:
    import random
    try:
        a = 1/random.random()
    except (ZeroDivisionError, SystemError):
        a = 0
    print("Done")
  2. Using multiple except clauses, for example:
    import random
    try:
        a = 1/random.random()
    except ZeroDivisionError:
        a = 0
    except SystemError:
        print("Warning: SystemError")
        a = 0
    print("Done")

3. Raising Exceptions

Exceptions are raised automatically if they are encountered and not handled in an 'except' clause.

The keyword 'raise' can be used to raise an exception by simply giving the exception type. The following raises a null.

raise SystemError

New types of exception can be defined by subclassing an exception from the builtins module.

4. Else and Finally

To run something only if exceptions are not raised, add an 'else' clause, for example:

import random
try:
    a = 1/random.random()
except:
    a = 0
else:
    print(a)
    # Exceptions here are raised.
print("Done")

To run code whether an exception is raised or not, then add a 'finally' clause, for example:

import random
try:
    a = 1/random.random()
except:
    a = 0
finally:
    if a == None:
        a = -1
print("Done")

5. System Exit

To exit a program at any point, call the 'exit function' from the sys module. For example:

import sys
sys.exit()

This has an arg option:

sys.exit(arg)

Where arg is a number that the system will report. Zero is usually regarded as exiting with no issues.

For details on error codes, see: errno - a special module on system error codes.