Python Exceptions

Exceptions occur when your program encounters an error. The program must handle the exception immediately or terminate. Python has many different types of exceptions to represent many different situations. Examples include: dividing by zero, using an out of range index value for a list, invalid syntax and types, running out of memory, and so on.

Most exceptions are non-fatal errors and when handled correctly will allow your program to continue. Some of the more common exceptions that you will see are as follows:

SystemExit is raised when calling the sys.exit() method, which stops the currently running script.

KeyboardInterrupt is raised when the user presses a key combination to abort the currently running script. In most terminal applications, the keystroke is CTRL+C.

ArithmeticError is the base class for arithmetic errors.

ZeroDivisionError is raised when trying to divide by zero.

LookupError is the base class for errors that arise when referencing collections.

IndexError is raised when trying to access a value with an index that lies outside the possible range of a list or tuple.

KeyError is raised when trying to access the key-value pair in a dictionary that does not contain the key specified.

NameError is raised when referencing a variable, function, or other object that does not exist.

RuntimeError is raised after the program passes the interpreter’s syntax checks but runs into a problem later. This may include typos in variable names, type conversion failures, wrong data types, and more.

SyntaxError is raised when the interpreter finds improper use of Python syntax.

IndentationError is raised when the interpreter encounters inconsistent use of spaces in your indentation.

SystemError is raised when something goes wrong with the interpreter.

TypeError is raised when an improper data type is encountered. For instance, when you try to divide a number by a string.

ValueError is raised when the data type is correct but the value is wrong.

Exception Handling

The Try-Except statement lets you execute a block of code and if an error occurs, allows you to handle that error gracefully.

In the following example, the names[4] statement will create an exception because the index is out of range. As a result, the print statement does not execute. However, the except block does.

names = ['Charlie', 'Lucy', 'Linus']
try:
	print(names[4])
except:
	print('An error occured')

It’s possible to stack multiple exception blocks together to handle different errors differently. In the following example, the print statement produces an IndexError exception and only the code in the IndexError exception is executed.

names = ['Charlie', 'Lucy', 'Linus']
try:
	print(names[4])
except IndexError:
	print('That index does not exist')
except:
	print('An unknown error occured')

Next, there is the try-except-else statement. In the example below, the print statement in the try block prints correctly, the except block is skipped, and the else block is executed.

try:
	print('Hello, World!')
except:
	print('Something went wrong!')
else:
	print('Everything is fine.')

Create Your Own Exception

You can manually raise your own exceptions. For instance, if you wanted to check user input when they enter their age, the following would raise an exception if the user enters a number less than 0 or greater than 100.

age = int(input('Enter your age: '))
if age < 0 or age > 100:
	raise ValueError('Age is not a valid number.')

Exception Propagation

When an exception occurs in Python, the interpreter looks for any suitable exception handler. Exceptions can be handled by any functions that are used to call that code.

In the following example, the divide() function raises an exception and passes it back to my_function() that passes it back to the try-except statement that was called, which then handles the exception.

def divide():
	num = 1/0

def my_function():
	divide()
	
try:
	my_function()
except ZeroDivisionError:
	print('Zero division error caught')
except:
	print('An unkown error occured')

As Python programs become larger and the code is split apart into different files and modules, it becomes important to handle exceptions as soon as they might occur.