Print Python Exception Error Hierarchy



We will learn about what an exception is before learning how to print Python exceptions.

An exception occurs when a program fails to execute in the direction it was intended to be. Python throws exceptions when unexpected errors or events occur.

It is common for exceptions to be both valid and invalid. Errors and exceptional conditions can be managed in a program through exceptions in a variety of ways. The exception handling technique can be used when you suspect your code may create an error. This can prevent the software from crashing. 

Following are some common Exceptions in Python -

  • IOError (Input Output Error) - When the file cannot be opened or accessed.
  • ImportError - When Python cannot find or load a module
  • ValueError - Occurs when the user hits the interrupt key (normally Ctrl + C or delete)
  • EOFError (End of File Error) - Caused when the input() or raw_input() encounters an end-of-file condition (EOF) without reading any data.

Python Exception/Error Hierarchy

Python Exception hierarchy consists of various built-in exceptions. This hierarchy is used to handle various types of exceptions, as the concept of inheritance also comes into picture.

In Python, all the built-in exceptions must be instances of a class derived from BaseException.

This Exception or Error hierarchy can be printed by importing Python's inspect module. Using the inspect module, one can perform type checking, retrieve the source code of a method, inspect classes and functions, and examine the interpreter stack.

Using inspect.getclasstree() Function

The inspect.getclasstree() function is used to print the hierarchy of exception classes. You can print the hierarchy of built-in exceptions and observe their relationships.

Syntax

Following is the basic syntax of the inspect.getclasstree() function -

inspect.getclasstree(classes, unique = False)

Example: Displaying Hierarchy of Built-in Exceptions

A hierarchy of nested lists of classes can be arranged using the inspect.getclasstree() function. Where the nested list appears, the classes that derive from the class immediately following will appear as well.

# Inbuilt exceptions:
# Import the inspect module
import inspect as ipt

# Function to print class hierarchy
def tree_class(cls, ind = 0):
   print ('-' * ind, cls.__name__)
   for K in cls.__subclasses__():
      tree_class(K, ind + 3)

print ("Inbuilt exceptions are: ")

# Using inspect.getmro() to get class hierarchy for BaseException
ipt.getclasstree(ipt.getmro(BaseException))

# Function call to print hierarchy of BaseException
tree_class(BaseException)

In this example, we only printed the hierarchy of BaseException; to print the hierarchy of other Exceptions, pass Exception as an argument to the function.

Inbuilt exceptions is:
BaseException
--- Exception
------ TypeError
------ StopAsyncIteration
------ StopIteration
------ ImportError
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
------ TokenError
------ StopTokenizing
------ ClassFoundException
------ EndOfBlock
--- GeneratorExit
--- SystemExit
--- KeyboardInterrupt

Example: Displaying Hierarchy of Other Exceptions

Another example used to display the Python Exception/Error hierarchy is as follows. Here, we are trying to display the hierarchy of other exceptions using Exception as the base class -

import inspect

print("The class hierarchy for built-in exceptions is:")

# Using inspect.getclasstree() to get class hierarchy for Exception
inspect.getclasstree(inspect.getmro(Exception))

# Function to print class hierarchy
def classtree(cls, indent=0):
   print('.' * indent, cls.__name__)
   for subcls in cls.__subclasses__():
      classtree(subcls, indent + 3)

# Function call to print hierarchy of Exception
classtree(Exception)

The output will display the hierarchy as follows -

The class hierarchy for built-in exceptions is:
Exception
... TypeError
... StopAsyncIteration
... StopIteration
... ImportError
...... ModuleNotFoundError
...... ZipImportError
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
... Verbose
... TokenError
... StopTokenizing
... EndOfBlock

Handling Exceptions in Python

Now that we understand what exceptions are and how to print the hierarchy, it is important to know how to handle exceptions properly in Python. Exception handling allows a program to continue running even if an error occurs.

Python provides several ways to handle exceptions, using the try, except, else, and finally blocks.

Using Try and Except Block

The basic structure for exception handling is using try and except block. The try block contains code that might cause an exception, while the except block contains code to handle the exception if it occurs.

Syntax

Following is the basic syntax of the try and except block in Python -

try:
    # Code that may raise an exception
except <ExceptionType> as e:
    # Code to handle the exception

Example: Handling a ZeroDivisionError

Let us say we are dividing two numbers and want to handle any potential ZeroDivisionError -

try:
   x = 5 / 0
except ZeroDivisionError as e:
   print(f"Error: {e}")

Following is the error obtained -

Error: division by zero

Using Else and Finally Blocks

The else block runs if no exception is raised, and the finally block always runs, whether an exception was raised or not. These blocks ensure that necessary clean-up actions are performed.

Syntax

Following is the basic syntax of the else and finally block in Python -

else:
    # Code that runs if no exception occurs
finally:
    # Code that runs no matter what

Example: Using Else and Finally

Let us consider a scenario where you want to open a file, read from it, and ensure that the file is closed properly whether an error occurs or not -

try:
   # Create and write to a file
   with open('example.txt', 'w') as f:
      f.write("Hello! This is a test file.")

   # Now try to read the file
   file = open('example.txt', 'r')
   content = file.read()
except FileNotFoundError as e:
   print(f"Error: {e}")
else:
   print("File read successfully:")
   print(content)
finally:
   file.close()
   print("File is closed")

We get the following output -

File read successfully:
Hello! This is a test file.
File is closed

Here, the file example.txt is created inside the try block and then opened for reading. The finally block guarantees that the file is closed even if an exception occurs.

Updated on: 2025-05-14T16:52:30+05:30

3K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements