Introduction

When exceptions occur, it causes the current process to stop and passes it to the calling process until it is handled. If not handled, program will crash.

For example, if function A calls function B which in turn calls function C and an exception occurs in function C. If it is not handled in C, the exception passes to B and then to A. If never handled, an error message is spit out and our program come to a sudden, unexpected halt.

 

Catching Exceptions

Exceptions can be handled using a try statement. A critical operation which can raise exception is placed inside the try clause and the code that handles exception is written in except clause.

import sys

randomList = ['a', 0, 2]

for entry in randomList:
  try:
    r = 1/int(entry)
    break
  except:
    print("Oops!",sys.exc_info()[0],"occured.")

 

The portion that can cause exception is placed inside try block. If no exception occurs, except block is skipped and normal flow continues. But if any exception occurs, it is caught by the except block.

 

Catching Specific Exceptions

A try clause can have any number of except clause to handle them differently but only one will be executed in case an exception occurs. We can use a tuple of values to specify multiple exceptions in an except clause. Here is an example pseudo code.

try:
  # do something
  pass
except ValueError:
  # handle ValueError exception
  pass
except (TypeError, ZeroDivisionError):
  # handle multiple exceptions i.e. TypeError and ZeroDivisionError
  pass
except:
  # handle all other exceptions
  pass

 

Raising Exceptions

Exceptions are raised when corresponding errors occur at run time, but we can forcefully raise it using the keyword raise. We can also optionally pass in value to the exception to clarify why that exception was raised.

try:
  a = int(input("Enter a positive integer: "))
  
  if a <= 0:
    raise ValueError("That is not a positive number!")
except ValueError as ve:
  print(ve)

 

Custom-made Exceptions

It’s possible to create custom exceptions. The best way to do this, consists in defining an exception class which inherits from the Exception class.

class MyException(Exception):
  pass

raise MyException("An exception!")

 

else Clause

Using the else statement, you can instruct a program to execute a certain block of code only in the absence of exceptions.

try:
  pass
except AssertionError as error:
  print(error)
else:
  print('Executing the else clause.')

 

finally Clause

The try statement in Python can have an optional finally clause. Finally clauses are called clean-up or termination clauses, because they must be executed under all circumstances, i.e. a “finally” clause is always executed regardless if an exception occurred in a try block or not.

try:
  x = float(input("Your number: "))
  inverse = 1.0 / x
except ValueError:
  print("You should have given either an int or a float")
except ZeroDivisionError:
  print("Infinity")
finally:
  print("There may or may not have been an exception.")