Python Exception Handling


In this article, you will learn about Python exception handling. You will learn in detail about the errors in Python, types of exceptions and the mechanism to handle the exceptions raised.

What is an Exception in Python?
Why use Exceptions?
Types of exceptions in Python
Built-in exceptions in Python
Handling Exceptions in Python
How to define Except clause with no exception?
How to define Except clause with multiple exceptions?
How to use try-finally clause?
User-Defined Exceptions

Python exception handling

What is an Exception in Python?

An exception simply is an error that occurs during the execution of a program.

When the Python program encounters a situation that disrupts the flow of the program, it raises an exception that can be handled.

If not handled properly, the interpreter throws a traceback error along with the statements that caused that error. These exceptions prevent the program from crashing.

Here is a simple example of ZeroDivisionError.

python_exception_example

Why use exceptions?

When we write a program, there might be some possible errors that can happen down the line. If there is no backup mechanism to handle these errors, the program will simply crash.

So, Python exception handling is a mechanism in which we define a backup plan for a possible error situation.

Types of Exceptions in Python

 

types of python exceptions

There are two types of exceptions in Python.

  • Built-in Exceptions
  • User-Defined Exceptions

Built-in Exceptions in Python


Built-in exceptions are the standard exceptions defined in Python. These exceptions are raised when the program encounters an illegal operation like semantic errors.

These built-in exceptions are generated either by the interpreter or the built-in functions of Python. The interpreter returns a string indicating the error code and the related information whenever an exception is raised.

 

Here is the tabulated list of some of the exceptions.

Python built-in exceptions and their causes
AssertionError
Raised in case of assertion statement failure.
AttributeError
Raised in case of attribute assignment failure.
EOFError
Raised when there is no input from either the raw_input() or input() function and the end of file is reached.
FloatingPointError
Raised when a floating point operation fails.
GeneratorExit
If a generator’s close() method gets called.
IOError
Raised if an input/output operation fails.
ImportError
Raised when the imported module is not available or found.
IndentationError
Raised when interpreter encounters incorrect indentation.
IndexError
Raised when the index of a sequence is out of range.
KeyError
Raised when a key is not found in a dictionary.
KeyboardInterrupt
Raised when the user hits interrupt key (Ctrl+c or delete).
MemoryError
Raised if an operation runs out of memory.
NameError
Raised when an identifier is not found in local or global scope.
NotImplementedError
Raised when an abstract method that needs to be implemented is not actually implemented.
OSError
Raised when system operation causes the system related error.
OverflowError
Raised when the result of an arithmetic operation exceeds the range.
ReferenceError
Raised when a weak reference proxy accesses a garbage collected reference.
RuntimeError
Raised when an error generated does not fall under any other category.
StopIteration
Raised when the next() method of an iterator does not point to any object.
SyntaxError
Raised when a syntactical error is encountered.
SystemError
Raised when interpreter detects an internal error.
SystemExit
Raised by sys.exit() function.
TabError
Raised by inconsistent tabs and spaces.
TypeError
Raised when a function is using an object of the incorrect type.
UnboundLocalError
Raised when trying to access a local variable in a function or method but no value has been assigned to it.
UnicodeError
Raised when a Unicode-related encoding or decoding error occurs.
UnicodeEncodeError
Raised when a Unicode-related error occurs during encoding.
UnicodeDecodeError
Raised when a Unicode-related error occurs during decoding.
UnicodeTranslateError
Raised when a Unicode-related error occurs during translating.
ValueError
Raised when a function receives invalid values.
ZeroDivisionError
Raised If the second operand of division or modulo operation is zero.

So, these are some of the built-in exceptions in Python. These all are derived from a base exception class. Every exception is derived from a base exception class. We will learn about creating custom exceptions later in this article.

Let’s learn about how exceptions are actually handled in Python.

Handling Exceptions in Python: try, except and finally

Exceptions are handled in Python using try statement where suspicious codes that may raise exceptions are placed inside the try block and the code that handle the raised exception is placed inside except block.

Here is the structure of try and except statement in Python.

try:
  ** Operational/Suspicious Code
except SomeException:
  ** Code to handle the exception

The try and except statements work as following.

  • First statements in try block are executed to check whether or not exception occurs
  • If exception doesn’t occur then the except block (except block contains statements to handle exceptions) is skipped after the execution of try block
  • If an exception occurs and matches the name defined 'SomeException' to handle in except block, it is handled and the program continues.
  • If no corresponding handler for the exception is found in except block, the program execution stops with the corresponding error message.
 

How to define Except clause with no exception?

Defining except clause is not the better approach for any programming because such try-except clause can handle all types of exceptions and users won’t be able to exactly identify the exception raised.

Syntax

try:
  #do your operations
except:
  #If there is any exception raised, execute these statements
else:
  #If there is no exception, execute these statements

Python Exception Handling: Example with no particular exception

Here is a simple example to catch an exception if a file we try to read doesn’t exist.

try:
  fp = open('example.txt', r)
except:
  print ('File is not found')
  fp.close

Here in this example, we have opened the file 'example.txt'. If the file is not found it will execute code in except block and 'File is not found' will be printed.

How to define Except clause with multiple exceptions?

A try statement can have multiple clauses to specify handlers of different exception. In above example, we have not defined any particular exception which is not considered good programming practice.

We can define multiple exceptions with the same except clause. Later during execution, if interpreter finds a matching exception, then it’ll execute the code written under the except clause.

Python Exception Handling: Example to handle multiple exceptions

We can use a tuple to specify multiple exceptions in an except clause. Here is an example showing how multiple exceptions are defined.

try:
   # do something

except (Exception1, Exception2, ..., ExceptionN):
   # handle multiple exceptions
   pass

except:
   # handle all other exceptions

How to use try-finally clause?

Beside try and except blocks, we can also use try and finally blocks together.

The finally block contains statements that must be executed whether or not the exception is caught and raised in the try block.

This is useful to release external resources and clear up the memories.

Here is the pseudo code for try..finally clause.

try:
   # perform operations
finally:
   #These statements must be executed

Python Exception Handling: Example to illustrate try..finally block

try:
   fp = open("example.txt",'r')
   #file operations
finally:
   fp.close()

This will ensure that file is closed after all the operations are done with.

User-Defined Exceptions


As the name goes by the exceptions defined by a user are called User-Defined Exceptions.

Sometimes in a program, we need create custom exceptions to serve our own purposes. Python also allows us to create our own exceptions by deriving classes from the standard built-in exceptions.

How to define a Custom Exception in Python?

We can create user-defined exceptions by creating a new class in Python. Directly or indirectly the custom exception class has to be derived from the base exception class. Most of the built-in exceptions are derived from this base class to enforce their exceptions.

>>> class UserDefinedError(Exception):
...     pass

>>> raise UserDefinedError
Traceback (most recent call last):
...
__main__.UserDefinedError

>>> raise CustomError("An error occurred")
Traceback (most recent call last):
...
__main__.UserDefinedError: An error occurred

As you can see in above example, we have created a user-defined exception class, the “UserDefinedError“ which is derived from the base Exception class as the parent. This user-defined exception class can raise exceptions as any other exception class by simply calling the “raise” statement with an optional error message.

We can define these user-defined class as our requirement and it’s better to place all these exceptions in a separate file for the ease.

Python Exception Handling: Example to illustrate User-defined exception

Let’s create a user-defined exception where the program will ask the user to input a number again and again until the user enters the correct stored number.

Here we will demonstrate how to raise an user-defined exception and catch errors in a program.

#User-defined exceptions
class Error(Exception):
   """Base class for other exceptions"""
   pass

#Define class for NegativeValueError
class NegativeValueError(Error):
  """Raised when the input is negative"""
  pass

#Define class for ValueTooSmallError
class ValueTooSmallError(Error):
   """Raised when the value is too small"""
   pass

#Define class for ValueTooLargeError
class ValueTooLargeError(Error):
   """Raised when the value is too large"""
   pass

#main program
#Takes input till the user inputs correct value

#Stored number
number = 11

while True:
   try:
       num = int(input("Enter a number: "))
       if num < 0:
           raise NegativeValueError
       elif num < number:
           raise ValueTooSmallError
       elif num > number:
           raise ValueTooLargeError
       break
   except NegativeValueError:
       print("This is a negative value, try again")
       print("")
   except ValueTooSmallError:
       print("This value is too small, try again")
       print("")
   except ValueTooLargeError:
       print("This value is too large, try again!")
       print("")

print("Correct value entered")

Here in this program, we have defined a base class Error from which three other exceptions NegativeValueError, ValueTooSmallError and ValueTooLargeError are derived.

Let’s try this program with multiple test values.

User defined exception example