Exception Handling Blocks
There are multiple things that could generate an exception in our code. Handling exceptions is done via the try-except block.
Try-Except Block
If there is a piece of code which could raise an exception (like ZeroDivisionError, IndexError, etc.), we can wrap it in a try-except block.
From the start of the try block till its end, any error that occurs will be caught and the flow of code will be directed to the except block.
Basic Syntax
try: # Body of the try block # Code that might raise an exceptionexcept Error1: # If an error called Error1 occurs, flow will be hereexcept Error2: # If an error called Error2 occurs, flow will be hereexcept: # Catch the rest of errors (not recommended - too broad)Example
try: x = int(input()) y = int(input()) print(x / y)except ZeroDivisionError: print("You have tried to divide by zero")except: print("Some error has occurred")Multiple Except Clauses
You can have multiple except clauses to handle different types of exceptions:
try: x = int(input()) y = int(input()) result = x / y print(result)except ZeroDivisionError: print("Cannot divide by zero")except ValueError: print("Invalid input. Please enter numbers only.")except Exception as e: print(f"An error occurred: {e}")The Else Clause
We can also have an else block which gets executed if no error has occurred:
try: x = int(input()) y = int(input()) result = x / y print(f"Result: {result}")except ZeroDivisionError: print("You have tried to divide by zero")except ValueError: print("Invalid input")else: print("No error has occurred - calculation successful")The Finally Clause
We can also have a finally block which gets executed regardless of whether we had an error or not. This is usually used for cleanup operations:
try: x = int(input()) y = int(input()) print(x / y)except ZeroDivisionError: print("You have tried to divide by zero")except: print("Some error has occurred")else: print("No error has occurred")finally: print("This is usually used for cleanup")Complete Example
try: x = int(input()) y = int(input()) result = x / y print(f"Result: {result}")except ZeroDivisionError: print("Cannot divide by zero")except ValueError: print("Invalid input. Please enter numbers only.")else: print("Calculation completed successfully")finally: print("This block always executes, regardless of success or failure.")Raising Exceptions
To throw an exception to the user, we use the raise keyword followed by the type of exception and an optional message:
raise Exception("An error has occurred")raise TypeError("Only integers are allowed")raise ValueError("Invalid value provided")Example: Custom Exception Raising
def calculate_square_root(number): if number < 0: raise ValueError("Cannot calculate square root of a negative number.") return number ** 0.5
def handle_square_root_calculation(number): try: result = calculate_square_root(number) print(f"The square root of {number} is: {result}") except ValueError as e: print(f"Error: {e}") finally: print("This block always executes, regardless of success or failure.")
handle_square_root_calculation(25) # Works finehandle_square_root_calculation(-16) # Raises ValueErrorException Information
You can capture exception information using the as keyword:
try: x = int(input()) y = int(input()) result = x / yexcept ZeroDivisionError as e: print(f"Error occurred: {e}") print(f"Error type: {type(e).__name__}")Exercises
Exercise 1: Safe Division with Error Handling
Write a function safe_divide that takes two numbers and returns their division. Handle ZeroDivisionError and TypeError exceptions. If division by zero occurs, return None. If a type error occurs, print “Invalid input types” and return None. Read two values from input and call the function.
Safe Division with Error Handling
def safe_divide(a, b): try: return a / b except ZeroDivisionError: return None except TypeError: print("Invalid input types") return None
x = int(input())y = int(input())result = safe_divide(x, y)print(result)Exercise 2: Factorial with Exception Handling
Write a function factorial that computes the factorial of a number. The function should read the number and raise a TypeError if the input is not an integer, and a ValueError if it is negative. Then write code that calls the function and handles these two errors using a try-except statement.
Factorial with Exception Handling
def factorial(n): if type(n) != int: raise TypeError("Input must be an integer") if n < 0: raise ValueError("Input must be non-negative") if n == 0 or n == 1: return 1 result = 1 for i in range(2, n + 1): result *= i return result
try: n = int(input()) result = factorial(n) print(result)except TypeError as e: print(f"TypeError: {e}")except ValueError as e: print(f"ValueError: {e}")Exercise 3: Try-Except-Else-Finally
Write code that reads two numbers, divides the first by the second, and uses try-except-else-finally blocks. In the try block, perform the division. In the except block, handle ZeroDivisionError and ValueError. In the else block, print “Division successful”. In the finally block, print “Cleanup complete”.
Try-Except-Else-Finally
try: x = int(input()) y = int(input()) result = x / y print(result)except ZeroDivisionError: print("Cannot divide by zero")except ValueError: print("Invalid input")else: print("Division successful")finally: print("Cleanup complete")