Python

How to Implement Error Handling in Your Python Code with Try and Except

Error handling is a process of handling and anticipating errors that may occur during the execution of a Python program. Error handling can be done with the help of the “try” and “except” blocks or statements to catch and handle the exceptions (errors) during the execution of the Python code.

We can check for errors in a block of code using the “try” statement. The “except” statement executes the code in the “except” block if an error happens and catch it. We can have multiple “except” blocks to catch the different types of errors or exceptions in the code.

Prerequisites:

If Python is not installed on a working computer, we need to download and install it. The official website allows for the download of Python.

Assume that while installing Python, you chose the option to incorporate it to the PATH. In that case, Python is usually installed in a directory like “C (Installation Drive):\Users\<USER NAME>\AppData\Local\Programs\Python\Pythonxx” where xx represents the version number (e.g., Python38).

If we don’t add Python to the PATH, it may be installed in a different directory, and we would need to navigate to the installation directory to run it.

Check the Python Installation

To verify that Python has been correctly installed and is present in the computer’s PATH environment variable after installation, launch the command line or terminal and enter the command that appears in the following:

>> python --version

 

Syntax:

try:
    # Enter Code that might raise an exception during running
except ExceptionType:
    # Code Block used to handle the exception

 

  • Replace the ExceptionType with the specific exception that you want to catch or use a more general exception to catch any exception.
  • If the “try” block encounters an exception of a specific type (or any type using Exception), the code that is contained in the “except” block will be carried out.

ZeroDivisionError Exception Example

Here is a fundamental example on how to use the “try” and “except” blocks to handle the errors. In this instance, the “try” block’s code attempts to divide 5 by 0. This raises a ZeroDivisionError exception. Any number, except 0, that is divisible by zero gives an infinite or zero division error. This exception is caught and printed to the user by the “except” block.

try:
  5 / 0
except ZeroDivisionError:
  print("Cannot divide by zero")

 

When we run the code using the Python compiler on the command line, it shows the following output on the screen:

Handling Specific Exceptions

The “try” and “except” commands in Python can be used to handle particular exceptions. We can check for faults in a code block using the “try” statement. The “except” statement executes the code in the “except” block if an error occurs and catch it. The developers can have multiple “except” blocks to catch different types of errors in their code.

To handle a specific exception, you can use the following syntax:

try:
    # Code that might raise an exception
except ExceptionName e:
    # Code to handle the exception

 

For example, the following code logs the error and provides a more detailed error message to the user if a FileNotFoundError exception is raised:

import logging
try:
  with open("products.txt", "r") as fileObj:
    contents = fileObj.read()
    print(contents)
except FileNotFoundError as e:
  logging.error(e)
  print(f"File '{e.filename}' does not exist")

 

If the “products.txt” file exists in the working directory, the following output is shown on the command prompt screen:

Raising Multiple Exceptions

The following given code raises an ArithmeticError exception if the second number is zero and it raises a TypeError exception if either of the numbers is not a number.

def divide_by_zero(number1, number2):
  if not isinstance(number1, (int, float)):
    raise TypeError("Number 1 must be a number")
  if not isinstance(number2, (int, float)):
    raise TypeError("Number 2 must be a number")
  if number2 == 0:
    raise ArithmeticError("Cannot divide by zero")
  return number1 / number2
# Example usage:
try:
  result = divide_by_zero('a', 5)
except ArithmeticError as e:
  print(e)
except TypeError as e:
  print(e)
else:
  print(result)

 

When we run the code using a Python compiler with different inputs, such as if number 2 is zero, the first output is displayed which raises an ArithmeticError exception. Similarly, if any number is input, it will be wrong if the number is not passed, a TypeError exception is raised.

Raising Custom Exceptions

Scenario: A user wants to divide two numbers using a calculator. However, the user might enter an invalid number or try to divide it by zero.

Implementation:

class InvalidNumberException(Exception):
    pass
class DivisionByZeroException(Exception):
    pass
class Calculator:
    def division(self, number1, number2):
        try:
            # Validate the numbers
            if not isinstance(number1, int) or not isinstance(number2, int):
                raise InvalidNumberException("Invalid number")

            # Check if the divisor is zero
            if number2 == 0:
                raise DivisionByZeroException("Cannot divide by zero")
            # Perform the division
            return number1 / number2
        except InvalidNumberException as e:
            print(e)
        except DivisionByZeroException as e:
            print(e)
# Create a calculator object
objCalculator = Calculator()
# Divide two numbers using the calculator
number1 = 10
number2 = 2
try:
    divisionResult = objCalculator.division(number1, number2)
except Exception as e:
    print("An error occurred:", e)
else:
    print("{} / {} = {}".format(number1, number2, divisionResult))

 

The DivisionByZeroException and InvalidNumberException exceptions are handled by this code. The code prints a notification to the user if one of these exceptions is raised.

Here is an example on how to use the code:

Numbers 1 and 2 should be changed to lines 29 and 30 to see the different output on the screen, respectively. If number1 and number2 have values of 10 and 2, respectively, the following output is displayed on the screen:

If the value of number1 is 10 and the value of number2 is “a”, the code throws the InvalidNumberException custom exception:

If the value of number2 is set to be 0, the DivisionByZeroException which is a custom exception is raised:

Using the “Else” and “Finally” Blocks

Using the “else” and “finally” blocks in an ATM Python code is handy for resource cleanup and graceful error handling. The “else” block is only activated when the function in the “try” block does not throw an exception. The “finally” block which is given after the “try and except” block is always executed, either an exception is raised by the code or not. Here’s an illustration on how to utilize the “else” and “finally” blocks in an ATM using Python:

class InvalidPinException(Exception):
    pass
class AtmOutOfCashException(Exception):
    pass
class ATM_Machine:
    def __init__(self):
        self.balance = 10000  # Set an initial balance for the ATM machine
    def withdraw_cash(self, amount, pinCode):
        try:
            # Validate the PIN
            if pinCode != "1234":
                raise InvalidPinException("Invalid Account PIN")
            # Check if the ATM machine has enough cash
            if amount > self.balance:
                raise AtmOutOfCashException("ATM is out of cash")
            # Withdraw the cash from the ATM machine
            self.balance -= amount
            # Return the cash to the customer
            return amount
        except InvalidPinException as e:
            print(e)
        except AtmOutOfCashException as e:
            print(e)        
# Create an ATM machine object
obj_ATM_Machine = ATM_Machine()
# Withdraw cash from the ATM machine
amount = 1000
pinCode = "1234"
try:
    cash = obj_ATM_Machine.withdraw_cash(amount, pinCode)
except Exception as e:
    print("An error occurred:", e)
else:
    print("You have withdrawn {}.".format(cash))
finally:
    print("Thank You!")

 

The InvalidPinException and AtmOutOfCashException are two unique exception classes that are defined in this code. Then, it creates a class called ATM_Machine whose constructor initially sets the balance at 10,000. The ATM_Machine class’s withdraw_cash() method verifies the PIN code and determines whether the machine has enough money. The method throws the appropriate exception if one of these conditions is not satisfied. If not, the procedure refunds the customer’s money after withdrawing it from the ATM machine.

The withdraw_cash() method is called in the main function of the code with the 1000 and “1234” parameters for the PIN code, creating an ATM machine object. Then, a “try and except” block is used to handle any potential exceptions. The main function prints a message to the user stating that the withdraw_cash() method succeeded in withdrawing the money. If not, the main function of the Python code prints a message with the error on the screen.

Regardless of whether an exception is raised or not, the main function’s “finally” block is always carried out. It delivers the user with a “Thank You!” message in print.

Here, the “else” and “finally” blocks are placed to execute. If there isn’t an exception in the “try” block, the “else” block is carried out:

The InvalidPinException is generated when the user enters an invalid PIN code:

The AtmOutOfCashException is raised:

The generic “Exception” class catches it if no exceptions are raised and the user enters an invalid amount; the parent class of all exceptions.

Conclusion

Exceptions are a powerful way to handle the errors in Python code. They allow the developers to handle the errors and gracefully provide helpful error messages to the end-users. We added multiple examples to better illustrate the error handling in Python.

About the author

Kalsoom Bibi

Hello, I am a freelance writer and usually write for Linux and other technology related content