Exception Handling Blocks

Learn how to handle exceptions using try-except blocks, else and finally clauses, and how to raise custom exceptions.

Ali Berro

By Ali Berro

6 min read Section 2
From: Python Fundamentals: From Zero to Hero

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-except-basic.py
try:
# Body of the try block
# Code that might raise an exception
except Error1:
# If an error called Error1 occurs, flow will be here
except Error2:
# If an error called Error2 occurs, flow will be here
except:
# Catch the rest of errors (not recommended - too broad)

Example

try-except-example.py
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:

multiple-except.py
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-except-else.py
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-except-finally.py
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

complete-example.py
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.py
raise Exception("An error has occurred")
raise TypeError("Only integers are allowed")
raise ValueError("Invalid value provided")

Example: Custom Exception Raising

custom-raise.py
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 fine
handle_square_root_calculation(-16) # Raises ValueError

Exception Information

You can capture exception information using the as keyword:

exception-info.py
try:
x = int(input())
y = int(input())
result = x / y
except 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

Checks: 0 times
Answer:
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

Checks: 0 times
Answer:
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

Checks: 0 times
Answer:
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")

Course Progress

Section 47 of 61

Back to Course