How To Catch And Print The Exception Messages In Python

How to catch and print the exception messages in Python

In Python programming, scripts often encounter unexpected situations they can’t handle. For instance, when writing a script that reads data from an external file, if the file doesn’t exist or has a permission issue, an exception may occur. These exceptions should be caught and reported to prevent the program from being terminated. Without proper exception handling, the program might abruptly terminate, leaving the user without feedback or results.

To address these challenges, it’s crucial to use exception handling techniques. These techniques enable the script to respond to unexpected events smoothly, prevent abrupt stops, and provide clear feedback when things deviate from the expected course. In this article, we will explore how to catch and print exception messages in Python, helping us better understand and debug such errors.

The simplest way to catch and print exception messages in Python is by using a try-except block. Enclose the code that might raise an exception within the try block, and use the except block to catch the specific exception. Utilize the ‘as’ keyword to store the exception message in a variable for printing or logging purposes.

Catching and Printing Exception Messages

Python provides exception handling through the try...except statement. In this structure, the code that may raise an exception is placed in the try block, while the code that handles the exception is placed in the except block.
Here’s a step-by-step guide on how to use this approach:
1. Enclose the code you want to monitor for exceptions within a try block.
2. Catch the exception using ‘except Exception as e’, where ‘e’ captures the exception object.
3. To print the exception message, you can use print(e) or logger.exception() module.
Now, let’s explore how you can use these methods to capture and handle different exceptions effectively in your Python code.

Catching different types of Exceptions

1) Catch and print ‘ValueError’

A ValueError is a built-in exception in Python that is raised when a problem arises with the type or value of a given argument or parameter. This exception is triggered when an appropriate data type (such as a string, integer, or floating-point number) is used within a function or operation, but the specific value provided is unsuitable or invalid for that particular operation. In simpler terms, it indicates that the data type is correct, but the value within that data type is inappropriate for the context in which it is used.

For instance, consider a scenario where you’re trying to convert a string that contains “2a” into an integer. Here, the data type (string) matches the expected input, but the value within it (“2a”) is unsuitable for integer conversion, resulting in the generation of a ValueError exception.

You can catch the ValueError exception using try and except statements. Inside the try block, we will take an input from the user and attempt to append it to the “new_list” variable. If the user enters anything other than an integer, the except block will display “Invalid entry” and proceed to the next value. Here’s a straightforward example that illustrates catching and handling a ValueError:

# Creating an empty list
new_list =[]

n = int(input("Enter number of elements : "))

for i in range(n):

  try:
    item = int(input())

    # Add the item in the list
    new_list.append(item)

  except:

    print("Invalid Input!")

    print("Next entry.")

print("The list entered by user is: ", new_list)

Output:

Enter number of elements : 7
65
43
23
4df
Invalid Input!
Next entry.
76
54
90
The list entered by user is:  [65, 43, 23, 76, 54, 90]

In this way, the program continues running while bypassing any invalid entries.

2) Catch and print ‘TypeError’

The TypeError typically arises when you use an operator, a function, or a method on objects that are not compatible or when you use them in a way that is not supported by their data types.

For instance, consider a scenario in which you possess a list comprising elements of different data types. Your objective is to divide all the integers by a specified number. However, attempting division with string data types within the list will result in a “TypeError.” If these exceptions are not effectively managed, they can lead to program termination.

The example provided below illustrates how to address this issue by capturing the exception using a try-except block.

list_arr=[76,65,87,"5f","7k",78,69]

for elem in list_arr:

  try:

    print("Result: ", elem/9)

  except Exception as e:

    print("Exception occurred for value '"+ elem + "': "+ repr(e))

Output:

Result:  8.444444444444445
Result:  7.222222222222222
Result:  9.666666666666666
Exception occurred for value '5f': TypeError("unsupported operand type(s) for /: 'str' and 'int'")
Exception occurred for value '7k': TypeError("unsupported operand type(s) for /: 'str' and 'int'")
Result:  8.666666666666666
Result:  7.666666666666667

You can also use logger.exception() module within the except block which produces an error message as well as the log trace. The log trace contains information such as the code line number at which the exception occurred and the time the exception occurred.

3) Catch and print ‘ZeroDivisionError’

A ZeroDivisionError is a built-in exception in Python that occurs when you attempt to divide a number by zero. Division by zero is mathematically undefined and leads to this exception. For instance, consider a program that takes two integers as input, performs division, and displays the result. If the user enters 0 as the second number, the program will encounter a ZeroDivisionError crash. Here’s an example that illustrates how you can catch this exception in this scenario and prevent the program from getting crashed:

import logging

logger=logging.getLogger()

num1=int(input("Enter the number 1:"))

num2=int(input("Enter the number 2:"))

try: 

  print("Result: ", num1/num2)

except Exception as e:

  logger.exception("Exception Occurred while code Execution: "+ str(e))

Output:

Enter the number 1:9
Enter the number 2:0
Exception Occurred while code Execution: division by zero
Traceback (most recent call last):
  File "<ipython-input-27-00694f615c2f>", line 11, in <module>
    print("Result: ", num1/num2)
ZeroDivisionError: division by zero

In the above code, the try block attempts the division operation, and if a ZeroDivisionError occurs, it is caught by the except block. The logger records the error, including the specific exception that occurred, and the program continues without crashing.

Similarly, if you have two lists consisting of integers and you want to create a list consisting of results obtained by dividing the elements of one list by the corresponding elements of another, you can use a similar approach to handle exceptions and log errors.

4) Catch And Print ‘IndexError’

A IndexError occurs when a user tries to access a sequence object (eg. list, tuple, array, range or string) outside its specified range. For instance, consider a program that takes a list with five elements (‘0’, ‘1’, ‘2’, ‘3’, ‘4’) as input, the user then tries to access the tenth element of the list. Since there is no tenth element in the list the program will throw an ‘IndexError: list index out of range’ and crash. Here’s an example that illustrates how you can catch this exception in this scenario and prevent the program from getting crashed:

list = [0, 1, 2, 3, 4]

try:
    element = list[10]
except IndexError as e:
    print(f"Exception Occurred while code Execution: {e}")
    element1 = list[1]
    print(f"Second element in the list: {element1}")

Output:

Exception Occurred while code Execution: list index out of range
Second element in the list: 1

5) Catch and print ‘IndentationError’

An IndentationError occurs when the programmer incorrectly indents the code. Indentation is part of syntax in python and indentation determines the structure of the code. Python specifically distinguishes between indentation error and syntax error to provide more informative error messages and help developers identify and fix issues more easily. While it is not a common or recommended practice to use except handling to resolve indentation errors – as developers should ideally correct the indentation directly – we can demonstrate how it could be achieved in code. Since indentation error occurs during parsing we use the exec function for code execution at runtime. The exec function in Python is a built-in function that is used for the dynamic execution of Python programs, statements, or expressions. Here’s an example where the exec statement tries to execute a code with indentation error but instead of crashing it the program continues to work:

code_with_indentation_error = '''
def my_function():
print('Indented code')
'''

try:
    exec(code_with_indentation_error)
except IndentationError as e:
    print(f"IndentationError: {e}")

Output:

IndentationError: expected an indented block after function definition on line 2 (<string>, line 3)

6) Catch and print ‘SyntaxError’

A SyntaxError is a the most common error in Python that occurs when a user uses wrong syntax in the code for example a misspelled word or a missing colon etc. Catching and printing a SyntaxError is a bit tricky because syntax errors are detected during the parsing phase before the code is executed. However we can catch the error using the try and except block to detect the error and by using the exec function. Here’s an example where the exec statement attempts to execute a string containing a syntax error (missing closing parenthesis in the print statement). The except block catches the SyntaxError, and the error message is printed:

try:
  exec("print('Hello, World!'")
except (SyntaxError, IndentationError) as e:
  print(f"Error during code execution: {e}")

valid_code = '''
print('This code has no syntax errors')
 x = 10
y = 20
print('Sum of x and y:', x + y)
'''
exec(valid_code)

Output:

Error during code execution: '(' was never closed (<string>, line 1)
This code has no syntax errors
Sum of x and y: 30

In the above code both the syntax and indentation error exceptions are used. First the syntax error identifies that there is no closing parenthesis and the next indentation error in the valid code can be seen so the indentation error identifies that error and ignores it while executing the valid code. In the valid code sum of two elements x and y is calculated and printed. This example demonstrates how indentation and syntax error are different in python even though indentation is part of syntax. It also demonstrates how both of these errors can be used together.

7) Catch and print ‘FileNotFoundError’

A FileNotFoundError is raised when Python attempts to access a file or directory that does not exist. It is a built-in exception and is part of the broader category of I/O (input/output) errors and is specifically used to handle cases where a file operation, such as opening or reading a file, is performed on a file that cannot be found at the specified path. However we can catch the error using the try and except block. Here’s an example where the user attempts to open a non-existent file. The except block catches the FileNotFoundError, and asks to provide a valid file path:

try:
  with open('nonexistent_file.txt', 'r') as file:
      content = file.read()
  print("File content:", content)
except FileNotFoundError as e:
  print(f"FileNotFoundError: {e}")
  print("File not found. Please provide a valid file path.")

Output:

FileNotFoundError: [Errno 2] No such file or directory: 'nonexistent_file.txt'
File not found. Please provide a valid file path.

In the above code the open function tries to open a file which does not exist in the system. The except command identifies that there is no such file and hence instead of crashing the program it prints the error statement while also printing the next statement which signifies that the program executes even after FileNotFoundError is identified.

Catching and printing Specific Exception messages

1) Catch and print exception Name

To retrieve the name of an exception we use __name__ attribute on the type of the exception. For this we use type(e).__name__. The code below demonstrates a ZeroDivisionError since we try to divide 100 by zero and the program prints the name of the exception occurred. Extracting the type only is also similar instead of adding the attribute __name__ we simply print the type of exception by type(e) built-in python function.

try:
  result = 100 / 0
except Exception as e:
  print(f"Exception Name: {type(e).__name__}")

Output:

Exception Name: ZeroDivisionError

2) Catch and print exception Details

The code is intentionally causing a TypeError by attempting to concatenate incompatible types, and the except block captures and prints information about the exception. If an exception occurs inside the try block, it is caught by the except block. The exception is assigned to the variable e. The code then extracts the type of the exception (type(e).__name__) and the string representation of the exception (str(e)).

try:
  result = [] + "string"
except Exception as e:
  error_type = type(e).__name__
  error_message = str(e)
  print(f"Error: {error_type}, Message: {error_message}")

Output:

Error: TypeError, Message: can only concatenate list (not "str") to list

3) Catch and print exception Arguments

We take the same example of ZeroDivisionError. The exception object e contains a tuple of arguments, which are accessed using e.args. We print the exception arguments/attributes using print("Exception Arguments/Attributes:", e.args). The args attribute is a tuple that contains the arguments passed to the exception constructor.

try:
    result = 10 / 0
except ZeroDivisionError as e:
    print("Exception Arguments/Attributes:", e.args)

Output:

Exception Arguments/Attributes: ('division by zero',)

4) Catch and print exception Traceback

To find the location where an exception occurred, you can use the traceback module. The traceback module in Python provides a way to extract and format stack traces and exception information. It is particularly useful for debugging and error reporting. The module includes functions for printing or formatting the current call stack, as well as capturing and formatting information about exceptions. The traceback.print_exc() line prints the traceback information, including the file name, line number, and function name where the exception occurred.

import traceback
try:
      result = 10 / 0 
except ZeroDivisionError as e:
      print("Traceback:")
      traceback.print_exc()

Output:

Traceback:
Traceback (most recent call last):
  File "/home/runner/ExcitableShamefulCommas/main.py", line 4, in <module>
    result = 10 / 0
ZeroDivisionError: division by zero

5) Catch and print exception Line Number

To extract the line number we must use the traceback as we did in the previous example.A “frame” refers to a single step in the call stack or execution stack. Each frame represents a specific point in the execution of a program. We then iterate through each frame in the traceback and print details such as the line number, and the corresponding line of code.

import traceback
try:
    result = 10 / 0 
except ZeroDivisionError as e:
    traceback_info = traceback.extract_tb(e.__traceback__)
    for frame in traceback_info:
        filename, line_number, func_name, line_text = frame
        print(f"Line: {line_number}")
        print(f"Code: {line_text.strip()}\n")

Output:

Line: 3
Code: result = 10 / 0

The output displays the line number where the error occurred, accompanied by the corresponding line of code.

6) Catch and print exception Cause

The code in the outer try block attempts to convert the string “abc” to an integer using int(“abc”). Since the non-numeric value prevents the conversion, it raises a ValueError. Inside the except block, another try block exists. The inner try block raises a RuntimeError with the message “Another error” using raise RuntimeError("Another error"). Within the inner except block, the code prints the cause of the RuntimeError using re.cause.

try:
  result = int("abc") 
except ValueError as ve:
  try:
      raise RuntimeError("Another error") from ve
  except RuntimeError as re:
      print(f"Cause of the Exception: {re.__cause__}")

Output:

Cause of the Exception: invalid literal for int() with base 10: 'abc'

This indicates that the ValueError caused the RuntimeError, and the printed message provides details about the original ValueError.

In summary, all of the methods described above are effective for capturing and handling exception messages in Python, depending on your specific requirements and comfort level with each method. If you have any questions or feedback regarding this article, please let us know in the comments. Your feedback is valuable to us.

Leave a Comment

Your email address will not be published. Required fields are marked *