Data StructuresDictionaries & SetsPython Basics

Python Exception Handling: try-except Blocks and Custom Errors

Production applications encounter unexpected situations, from unreadable files to dropped network connections. Without robust error handling, unhandled exceptions cause applications to crash instantly. Python exception handling enables software to catch runtime errors gracefully, execute fallback routines, and maintain operational stability.

This guide covers try-except blocks, handling multiple exception types, using else and finally clauses, and defining custom exceptions.

Key Takeaways

  • Wrap code prone to runtime errors inside try blocks and catch exceptions with except clauses.
  • Always catch specific exceptions (e.g., ValueError, FileNotFoundError) rather than bare except: statements.
  • The else block executes only when no exceptions occur; the finally block runs unconditionally for cleanup tasks.
  • Custom exceptions are created by inheriting from Python’s built-in Exception class.

1. The Structure of Exception Handling

Catch errors using specific exception types to prevent your program from halting unexpectedly.

Python

def execute_division(numerator, denominator):
    try:
        result = numerator / denominator
    except ZeroDivisionError as error:
        print(f"[ERROR] Invalid operation: {error}")
        return None
    else:
        print("[SUCCESS] Calculation completed with no errors.")
        return result
    finally:
        print("[SYSTEM] Cleanup routine executed.")

# Safe execution
output = execute_division(100, 0)

2. Handling Multiple Exception Types

An operation can fail for multiple reasons. Chain multiple except blocks or pass a tuple of exceptions to handle distinct failure modes separately.

Python

import json

def parse_configuration(file_path):
    try:
        with open(file_path, "r") as file:
            data = json.load(file)
            return data["database_port"]
            
    except FileNotFoundError:
        print(f"[FAIL] Configuration file '{file_path}' missing.")
    except json.JSONDecodeError:
        print(f"[FAIL] File '{file_path}' contains malformed JSON.")
    except KeyError:
        print("[FAIL] Required key 'database_port' absent from JSON.")

3. Creating Custom Exceptions

Define domain-specific custom exceptions to communicate business logic errors clearly across large codebases.

Python

class InsufficientPrivilegesError(Exception):
    """Raised when a user attempts an unauthorized administrative action."""
    def __init__(self, user_role, required_role="Admin"):
        self.user_role = user_role
        self.required_role = required_role
        super().__init__(f"Role '{user_role}' lacks required permissions ('{required_role}').")

def AccessControlModule(user):
    if user["role"] != "Admin":
        raise InsufficientPrivilegesError(user_role=user["role"])

# Triggering custom error handling
try:
    AccessControlModule({"username": "dev_user", "role": "Guest"})
except InsufficientPrivilegesError as err:
    print(f"Access Denied: {err}")

4. Exception Hierarchy Reference

ClassPurposeTypical Trigger
BaseExceptionRoot class for all exceptions (avoid catching directly)System exit, keyboard interrupt
ExceptionBase class for user-defined and standard errorsStandard runtime errors
ValueErrorCorrect data type passed, but invalid value providedint("invalid_string")
TypeErrorIncompatible data type passed to function or operator"text" + 42

Conclusion

Mastering Python exception handling separates fragile scripts from resilient software. Catching specific errors, executing cleanup via finally, and defining custom error classes guarantees that your application recovers predictably from unexpected failures.

Leave a Reply

Your email address will not be published. Required fields are marked *