Python Exception

In this tutorial let’s see how exception differs from syntax error and how to handle the Python exception in the code. The normal flow of execution of a program can be disrupted by:

  • Syntax error
  • Exception

How Syntax errors differ from Python Exception

Syntax error

A syntax error is an error in the syntax of a sequence of characters or tokens that are caught by the compiler. The syntax errors have to be corrected for the program to compile successfully. Here are a few examples of syntax error:

>>> print(1233))
  File "<stdin>", line 1
    print(1233))
               ^
SyntaxError: invalid syntax

The arrow mark indicates that there is a syntax error while parsing the code. The error is due to too many brackets. Correct the code by removing the unwanted brackets and run the code.

>>> if True:
... print('YES')
  File "<stdin>", line 2
    print('YES')
        ^
IndentationError: expected an indented block

The above code ran into an error because there is no indentation between the if statement and the following line. Correct the indentation to resolve the error.

Python Exception

Exception error will occur when the code is syntactically correct but there is an error in the code itself. Here is an example of a Python exception:

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

Instead of simply showing ‘Exception Error’, Python clearly mentions what type of exception error you ran into. In this case, it’s ‘ZeroDivisionError’. Python not only comes with its own built-in exceptions but also allows programmers to create their own exceptions in Python.

How to raise an Exception in Python

As a programmer, you can choose to throw an exception based on conditions.

Use ‘raise’ keyword to throw an exception in Python, if a certain condition occurs.

x=5
while(x>=0):
    print(x)
    x-=1
else:
    raise Exception("Negative numbers are not allowed")

The output of the above code will be:

5
4
3
2
1
0
Traceback (most recent call last):
  File "sample.py", line 6, in <module>
    raise Exception("Negative numbers are not allowed")
Exception: Negative numbers are not allowed

This program stops and displays the execution message in the console.

AssertionError Exception in Python

Prior to running the module, using the assert statement, a programmer can declare the condition to be true while writing the code. If the condition is True, the next line of code will get executed, else the program throws an AssertionError exception.

Python Exception

x=5
assert x==5

The above code doesn’t throw any error since the assertion condition is True. Change the condition to make the assertion fail and run the code again.

File "sample.py", line 2, in <module>
    assert x==7
AssertionError

Whenever the program encounters an exception, the program stops abruptly. If you want your program to continue even after the exception, then you have to handle the exception in the program.

Handling Python Exception

We handle the exception in Python using try and except block. The code written inside the try block will get executed whenever the program is run. The code inside the except block will get executed if there is an exception caused by the code inside the try block. That means the code inside the except block is a response to the exception caused by the code inside the try block.

try:
    {
    Code gets executed normally when the program runs
    }
except:
    {
    Code gets executed if there is an exception
    }

As we have seen already, the syntax errors are not an exception. In the case of Python exception, the program stops abruptly due to unhandled exceptions caused by the syntactically correct code. You can add an except block, to handle the exception in Python and the program continues after that.

IndexError Exception in Python

Let’s see an example of how to handle the IndexError exception in Python:

def get_item_by_index(arr,ind):
    l=len(arr)
    print(arr[ind])

l=[1,2,3,4,5]

The function get_item_by_index() accepts a list and index as an input. If the index is within the limits then it prints the list element of that index. If not, we will get an error.

1
Traceback (most recent call last):
  File "sample.py", line 7, in <module>
    get_item_by_index(l,-6)
  File "sample.py", line 4, in get_item_by_index
    print(arr[ind])
IndexError: list index out of range

Let’s call the function inside the try block:

try:
    get_item_by_index(l,-5)
    get_item_by_index(l,-6)
except:
    pass
print('Exception is handled properly')

In the except block, we are handling the Python exception with a simple ‘pass’ statement. Now, the output is:

1
Exception is handled properly

If we pass an index outside the limits of the list, we get nothing. Otherwise, for a valid index, we get the list element for that index. The program does not crash because of the exception and it starts executing the next line after the except block.

Instead of the pass statement, we can give a message about a piece of information on the error.

try:
    get_item_by_index(l,-5)
    get_item_by_index(l,-6)
except:
    print('Index out of limits')
print('Exception is handled properly')

Run the code again, and the output will be:

1
Index out of limits
Exception is handled properly

The above code not only continues running even if there is an exception but also displays information on what kind of error is thrown because of the exception.

To see the exact error, we need to catch the actual error thrown by the function.

try:
    get_item_by_index(l,-5)
    get_item_by_index(l,-6)
except IndexError as e:
    print(e)
    print('Index out of limits')
1
list index out of range
Index out of limits

The first message is the IndexError explaining that you are accessing an index out of list range. The second message is the one that we are printing to the console.

In this example, we have created our own function and caught the IndexError and displayed the error message in the console.

FileNotFoundError Exception in Python

Let’s see one more example where we open a file and handle the Python exception.

try:
    with open('input.txt') as file:
        input_data=file.read()
except:
    print('Could not open "input.txt"')

If there is no such file ‘input.txt’, then you will get the below error:

Could not open "input.txt"

This is the error message we are printing to the console and the program continues to run. There are a lot of built-in exceptions available for us to use. We are going to pick one of them and discuss them in detail.

Whenever is a requested file or directory is not found, we can make use of FileNotFoundError exception.

Capture the exception and print it to the screen.

except FileNotFoundError as e:
    print(e)
    print('Could not open "input.txt"')

The error when the file is not found:

[Errno 2] No such file or directory: 'input.txt'
Could not open "input.txt"

Multiple function calls inside the try block

We can also have more than one function call inside the try block and handle various python exceptions.

try:
    get_item_by_index(l,-6)
    with open('file.log') as file:
        read_data = file.read()
except FileNotFoundError as e:
    print(e)
except IndexError as e:
    print(e)

We are expecting two error messages, one for index error and other for file not found error. Let’s check the output:

list index out of range

We have got only one error message that’s because the try block will be exited as soon as the exception occurs. The code inside the try block runs until it encounters the exception.

If we pass a valid index and file is not found, then we will get the below message.

5
[Errno 2] No such file or directory: 'file.log'

Avoid using bare except because it masks all the errors even the unexpected ones. Refer to the specific Python exception classes instead and handle those.

Else clause

The code inside the else statement gets executed only if there is no exception.

try: 
  { 
    Code gets executed normally when the program runs 
  } 
except: 
  { 
    Code gets executed if there is an exception 
  }
else:
  {
    Code gets executed if only there is no exception 
  }

The following example explains the usage of else statement.

try:
    get_item_by_index(l,-1)
except IndexError as e:
    print(e)
else:
    print('Else is getting executed')

Pass a valid index to see if the statement inside the else is getting printed.

5
Else is getting executed

We can also catch exceptions inside the else statement.

try:
    get_item_by_index(l,-1)
except IndexError as e:
    print(e)
else:
    try:
        with open('file.log') as file:
            read_data = file.read()
    except FileNotFoundError as e:
        print(e)

Pass a valid index and check the output:

5
[Errno 2] No such file or directory: 'file.log'

Since we have passed the valid index, there is no exception hence the code inside the else statement gets executed. There is a try and except statement inside the else statement. If there is an exception inside the else block, it will be caught and handled.

finally

The finally block does some clean-up after the code execution.

try: 
  { 
    Code gets executed normally when the program runs 
  } 
except: 
  { 
    Code gets executed if there is an exception 
  } 
else: 
  { 
    Code gets executed if only there is no exception 
  }
finally:
  {
    Always run this code
  }

Let’s add finally block to the previous code.

try:
    get_item_by_index(l,-1)
except IndexError as e:
    print(e)
else:
    try:
        with open('file.log') as file:
            read_data = file.read()
    except FileNotFoundError as e:
        print(e)
finally:
    print('Cleaning Up')

The code inside finally block gets executed no matter what. It’s doesn’t matter if there is an exception inside try or else statement or there is no exception at all.

5
[Errno 2] No such file or directory: 'file.log'
Cleaning Up

Summary

Here are the key things to remember for Python exception:

  • Use raise keyword to throw an exception at any time.
  • assert keyword checks for a specific condition. If the condition is False, throws an exception.
  • The code inside the try block gets executed until it encounters the Python exception.
  • except catches and handles the exception thrown by the code inside the try block.
  • Code inside the else block gets executed only if there is no exception.
  • Code inside the finally block executed always irrespective of Python exception.
Translate ยป