Python Exception Handling

Back to home
Logicmojo - Updated Nov 11, 2021



Various faults will always occur during the programming process. Our code is at blame for some of the issues. For example, a syntax error. This type of issue is commonly referred to as a bug. The flaw must be addressed. However, even a bug-free programme might have issues. Because some errors are caused by factors other than our programming. They can be brought on by unintentional events or operations. Exceptions are the name for this type of problem.

⮞ The disc may be full and cannot be written into while writing data to files.
⮞ The network goes down when some data is being downloaded.
⮞ Enter 0 as the denominator when dividing.
Not only is the code bug-free, but it also handles exceptions well.

Why do we need Exception Handling?

For the following reasons, exception handling is required:

⮞ Error Handling: If an error occurs during runtime, the application may terminate without warning. Using Exception Handling, we can manage failure scenarios and keep the programme from terminating.

⮞ Code Separation: Error Handling can assist us in separating the error-handling code from the core logic. The error-related code can be contained within the "except" block, which separates it from the ordinary code containing the application logic.

⮞ Error Type and Error Differentiation Grouping: This can assist us separate different types of errors that occur throughout the execution. Multiple "except" blocks can be used, each handling a different type of mistake. We'll explore how to use numerous "except" blocks to handle different types of errors in the article following.

Errors can be of various types:

Syntax Error
Out of Memory Error
Recursion Error
Exceptions
Let's see them one

Syntax Error: Syntax errors, also known as parsing errors, occur when the parser finds a syntactic problem in your code.
Out of Memory Error: Memory problems are primarily caused by your system's RAM and are associated with Heap. OutofMemoryError will appear if you have huge objects (or) referenced objects in memory (Source).

Recursion Error: It is related to stack and occurs when you call functions. As the name suggests, recursion error transpires when too many methods, one inside another is executed (one with an infinite recursion), which is limited by the size of the stack.

Indentation Error: Indentation errors are comparable to syntax errors in spirit and are classified as such. However, this is just applicable to the script's indentation concerns.

Exceptions versus Syntax Errors

When the parser identifies an erroneous statement, syntax errors occur. Take a look at the following example.

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

The arrow shows where the parser encountered a syntactic error. There was one bracket too many in this case. Remove it and rerun your programme:

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

You encountered an exception error this time. When syntactically correct Python code produces an error, this is the type of error that occurs. The message's last line specified the type of exception error you encountered.

Instead of displaying the message exception error, Python displays information about the sort of exception error that occurred. It was a ZeroDivisionError in this situation. Python includes a number of built-in exceptions, as well as the ability to construct custom exceptions.

Raising an Exception

If a condition occurs, we can use raise to throw an exception. A custom exception can be used in conjunction with the statement.

x = 10
if x > 5:
    raise Exception('x should not exceed 5. The value of x was: {}'.format(x))

When you run this program the application halts and shows our exception on the screen, providing hints as to what went wrong.

Finally Block in try-except

Finally, whether or not an exception occurs during programme execution, Block contains all the execution statements that must be executed. Regardless of success or failure, the statement inside "finally" will run. Let's look at a scenario to assist us grasp this.

Let's use the File system as an example. We're going to open a file stream to read a file from the directory. The application could encounter an error when reading the file, or it could read the file without encountering any errors. However, we wish to close the file stream that was opened in both of these circumstances. We could waste a lot of memory if we don't close the file stream at the end of the programme.

A "finally" block can be used to perform logic that must be completed regardless of whether it succeeds or fails.

def readFileContent():
  fileReader = None
  try:
    fileReader = open("a.json")
    print(fileReader.read())
  except: 
    print("Cannot Read the specified File")
  finally:
    print("Closing File Reader...")
    fileReader.close()

readFileContent()

Because the file we're trying to read may or may not exist in the above code, the function to open the file reader may fail. However, regardless of whether the file was read or not, we must close this reader in the above situation. Even if there is an error, the "finally" block is executed, and the file reader is closed.

The AssertionError Exception

Rather than waiting for a programme to crash in the middle, you can start by asserting something in Python. We claim that a certain criterion has been met. If this condition turns out to be correct, that's fantastic! It is possible to continue the programme. You can have the application throw an AssertionError exception if the condition turns out to be False.

Consider the following example, in which it is stated that the code will be run on a Linux system:

import sys
assert ('linux' in sys.platform), "This code runs on Linux only."

The claim is true if you run this code on a Linux machine. If you ran this code on a Windows system, the assertion would result in False, and the output would be as follows:

Traceback (most recent call last):
  File "<input>", line 2, in <module>
AssertionError: This code runs on Linux only.

Handling Multiple Exception Clause

For a single "try" block, we can have many "except" blocks. If there are numerous unless blocks, the one with the most specific exception is performed. Let's look at an example to demonstrate this.

def implementDivision(a, b):
  try:
    value = a/b
    print(value)
  except FileNotFoundError:
    print("The File Cannot be Found")
  except ZeroDivisionError:
    print("Number Cannot be Divided by Zero")
  except:
    print("This is the Generic Error")

implementDivision(10, 0)

Multiple exceptions in a single except clause

The above syntax has a shortcut (not exactly). Here's how it works in general:

try:
    # exception prone code here	
except (exception_1, exception_2, .... ,exception_n):
    # code to be executed once the exception is handled


Learn More

The else Clause

Using the else statement in Python, you may tell a programme to only run a given block of code if there are no exceptions.

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

The else clause was executed because the programme did not encounter any exceptions. You can also try running code inside the otherwise clause to see if any exceptions arise:

try:
    linux_interaction()
except AssertionError as error:
    print(error)
else:
    try:
        with open('file.log') as file:
            read_data = file.read()
    except FileNotFoundError as fnf_error:
        print(fnf_error)

Summary

⮞ You can throw an exception at any time with raise.
⮞ You can use assert to check if a condition is met and throw an exception if it isn't.
⮞ All statements are performed until an exception is discovered in the try clause.
⮞ The exception(s) found in the try clause are caught and handled with except. else allows you to write sections that should only run if there are no exceptions in the try clause.
⮞ Finally, with or without any previously encountered exceptions, you can run pieces of code that should always run.

Good luck and happy learning!