codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
🐍

Python Programming

48 / 68 topics
45Python File Handling (Read/Write/Delete)46Reading & Writing CSV Files47Python Exception Handling48Python Custom Exceptions
Tutorials/Python Programming/Python Custom Exceptions
🐍Python Programming

Python Custom Exceptions

Updated 2026-05-15
15 min read

Python Custom Exceptions

In this tutorial, you'll learn how to create custom exception classes by inheriting from Python's built-in Exception class. You'll also explore the raise statement for manually throwing exceptions and the assert statement for debugging purposes. Understanding these concepts will help you write more robust and maintainable code.

Introduction

Custom exceptions allow you to define specific error types that are relevant to your application. This makes your code more readable and easier to debug, as it clearly communicates what went wrong in a particular context. By inheriting from the Exception class, you can extend the functionality of built-in exceptions and create tailored error handling mechanisms.

Creating Custom Exception Classes

To create a custom exception, you simply define a new class that inherits from Python's Exception class. This allows you to add additional attributes or methods if needed.

Example 1: Basic Custom Exception

Let's start by creating a simple custom exception for invalid user input.

custom_exception.py
1class InvalidInputError(Exception):
2 """Custom exception for invalid user input."""
3 pass
4
5# Raising the custom exception
6try:
7 user_input = int(input("Enter a positive number: "))
8 if user_input <= 0:
9 raise InvalidInputError(f"{user_input} is not a positive number.")
10except InvalidInputError as e:
11 print(e)
Output
Enter a positive number: -5
-5 is not a positive number.

In this example, we define a custom exception class InvalidInputError that inherits from Exception. We then use the raise statement to throw this exception when the user input is not a positive number. The exception message is displayed in the except block.

Example 2: Custom Exception with Attributes

You can also add attributes to your custom exceptions to provide more context about the error.

custom_exception_with_attributes.py
1class InvalidInputError(Exception):
2 """Custom exception for invalid user input."""
3 def __init__(self, message, value):
4 super().__init__(message)
5 self.value = value
6
7# Raising the custom exception with attributes
8try:
9 user_input = int(input("Enter a positive number: "))
10 if user_input <= 0:
11 raise InvalidInputError(f"{user_input} is not a positive number.", user_input)
12except InvalidInputError as e:
13 print(f"Caught an error: {e}. Value was {e.value}")
Output
Enter a positive number: -10
Caught an error: -10 is not a positive number. Value was -10

Here, we extend the InvalidInputError class to include an additional attribute value, which stores the invalid input value. This can be useful for debugging or logging purposes.

The raise Statement

The raise statement is used to manually throw an exception in your code. You can raise built-in exceptions or custom exceptions as needed.

Example 3: Raising Built-in Exceptions

Let's see how you can use the raise statement with a built-in exception.

raising_builtin_exception.py
1def divide_numbers(a, b):
2 if b == 0:
3 raise ZeroDivisionError("Cannot divide by zero.")
4 return a / b
5
6try:
7 result = divide_numbers(10, 0)
8except ZeroDivisionError as e:
9 print(e)
Output
Cannot divide by zero.

In this example, the divide_numbers function raises a ZeroDivisionError when the divisor is zero. The error message is then caught and printed in the except block.

The assert Statement

The assert statement is used for debugging purposes. It checks if a given condition is true, and if not, it raises an AssertionError. This can be helpful during development to ensure that certain assumptions about your code are correct.

Example 4: Using the assert Statement

Let's use the assert statement to validate user input.

using_assert.py
1def process_input(user_input):
2 assert isinstance(user_input, int), "Input must be an integer."
3 if user_input < 0:
4 raise ValueError("Negative numbers are not allowed.")
5 return f"Processed {user_input}"
6
7try:
8 result = process_input(-5)
9except AssertionError as e:
10 print(e)
11except ValueError as e:
12 print(e)
Output
Input must be an integer.

In this example, the assert statement checks if user_input is an integer. If not, it raises an AssertionError with a custom message. This helps catch bugs early in development.

Practical Example

Let's create a complete program that uses custom exceptions and the raise and assert statements to handle file operations safely.

file_operations.py
1class FileReadError(Exception):
2 """Custom exception for file read errors."""
3 pass
4
5def read_file(file_path):
6 try:
7 with open(file_path, 'r') as file:
8 content = file.read()
9 assert len(content) > 0, "File is empty."
10 return content
11 except FileNotFoundError:
12 raise FileReadError(f"File not found: {file_path}")
13 except AssertionError as e:
14 raise FileReadError(str(e))
15
16try:
17 file_content = read_file("example.txt")
18 print(file_content)
19except FileReadError as e:
20 print(e)

In this example, we define a custom exception FileReadError for handling file-related errors. The read_file function attempts to open and read a file. If the file is not found, it raises a FileReadError. If the file is empty, it also raises a FileReadError using an assert statement.

Summary

  • Custom Exceptions: Inherit from Exception to create custom error types that are specific to your application.
  • raise Statement: Use raise to manually throw exceptions when needed.
  • assert Statement: Use assert for debugging purposes to ensure assumptions about your code are correct.

By using these techniques, you can write more robust and maintainable Python applications with clear error handling mechanisms.

What's Next?

In the next tutorial, we'll explore how to interact with MySQL databases in Python. You'll learn how to perform basic CRUD operations such as Create, Insert, Select, Update, and Delete. This will provide a solid foundation for working with relational databases in your Python projects.

Stay tuned!


PreviousPython Exception HandlingNext Python MySQL (Create, Insert, Select, Update, Delete)

Recommended Gear

Python Exception HandlingPython MySQL (Create, Insert, Select, Update, Delete)