How to define a custom exception class in Python with an error code attribute

Create a custom exception class with extra attributes like an error code, then raise and catch it in a try/except block.

Easy Python 3.9+ Aug 9, 2026 OOP & classes 15 views 0 copies

Python code

19 lines
Python 3.9+
class UserNotFoundError(Exception):
    def __init__(self, user_id, error_code=404):
        self.user_id = user_id
        self.error_code = error_code
        super().__init__(f"User with ID {user_id} was not found (error code: {error_code})")

def find_user(user_id, users_db):
    if user_id not in users_db:
        raise UserNotFoundError(user_id)
    return users_db[user_id]

if __name__ == "__main__":
    users = {1: "Alice", 2: "Bob"}
    try:
        find_user(3, users)
    except UserNotFoundError as e:
        print(f"Caught exception: {e}")
        print(f"Error code attribute: {e.error_code}")
        print(f"User ID attribute: {e.user_id}")

Output

stdout
Caught exception: User with ID 3 was not found (error code: 404)
Error code attribute: 404
User ID attribute: 3

How it works

UserNotFoundError inherits from Exception, so it behaves like any built-in exception in try/except. The custom __init__ stores extra attributes (user_id, error_code) before calling super().__init__ with a formatted message. Raising it with raise UserNotFoundError(user_id) passes the user ID and defaults the error code to 404. Catching the exception as e lets you access both attributes, which is useful for logging or API responses.

Common mistakes

  • Forgetting to call `super().__init__()` inside the custom exception's `__init__` method
  • Not passing extra arguments when raising, so the error code defaults silently
  • Using bare `except:` instead of catching the specific custom exception

Variations

  1. Add a `status_code` property that returns `self.error_code` for consistency with HTTP responses.
  2. Make the error code a required positional argument by removing its default value.

Real-world use cases

  • Raising a `UserNotFoundError` from a REST API endpoint, then mapping the attribute to an HTTP 404 status in the framework's error handler.
  • In a CLI tool, catching a custom `ConfigValidationError` with an `error_code` attribute to exit with a specific process exit code.
  • In an ETL pipeline, raising a `SchemaMismatchError` that carries a data row ID and an error code for downstream alerting and retry logic.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from OOP & classes

Related tutorials and quizzes for this topic.