• About
  • Privacy Policy
  • Disclaimer
  • Contact
Soft Bliss Academy
No Result
View All Result
  • Home
  • Artificial Intelligence
  • Software Development
  • Machine Learning
  • Research & Academia
  • Startups
  • Home
  • Artificial Intelligence
  • Software Development
  • Machine Learning
  • Research & Academia
  • Startups
Soft Bliss Academy
No Result
View All Result
Home Machine Learning

5 Error Handling Patterns in Python (Beyond Try-Except)

softbliss by softbliss
June 7, 2025
in Machine Learning
0
5 Error Handling Patterns in Python (Beyond Try-Except)
0
SHARES
0
VIEWS
Share on FacebookShare on Twitter


5 Error Handling Patterns in PythonImage by Author | Canva

 

When it comes to error handling, the first thing we usually learn is how to use try-except blocks. But is that really enough as our codebase grows more complex? I believe not. Relying solely on try-except can lead to repetitive, cluttered, and hard-to-maintain code.

In this article, I’ll walk you through 5 advanced yet practical error handling patterns that can make your code cleaner, more reliable, and easier to debug. Each pattern comes with a real-world example so you can clearly see where and why it makes sense. So, let’s get started.

 

1. Error Aggregation for Batch Processing

 
When processing multiple items (e.g., in a loop), you might want to continue processing even if some items fail, then report all errors at the end. This pattern, called error aggregation, avoids stopping on the first failure. This pattern is excellent for form validation, data import scenarios, or any situation where you want to provide comprehensive feedback about all issues rather than stopping at the first error.

Example: Processing a list of user records. Continue even if some fail.

def process_user_record(record, record_number):
    if not record.get("email"):
        raise ValueError(f"Record #{record_number} failed: Missing email in record {record}")
    
    # Simulate processing
    print(f"Processed user #{record_number}: {record['email']}")

def process_users(records):
    errors = []
    for index, record in enumerate(records, start=1):  
        try:
            process_user_record(record, index)
        except ValueError as e:
            errors.append(str(e))
    return errors

users = [
    {"email": "[email protected]"},
    {"email": ""},
    {"email": "[email protected]"},
    {"email": ""}
]

errors = process_users(users)

if errors:
    print("\nProcessing completed with errors:")
    for error in errors:
        print(f"- {error}")
else:
    print("All records processed successfully")

 
This code loops through user records and processes each one individually. If a record is missing an email, it raises a ValueError, which is caught and stored in the errors list. The process continues for all records, and any failures are reported at the end without stopping the entire batch like this:

Output:
Processed user #1: [email protected]
Processed user #3: [email protected]

Processing completed with errors:
- Record #2 failed: Missing email in record {'email': ''}
- Record #4 failed: Missing email in record {'email': ''}

 

2. Context Manager Pattern for Resource Management

 
When working with resources like files, database connections, or network sockets, you need to ensure they’re properly opened and closed, even if an error occurs. Context managers, using the with statement, handle this automatically, reducing the chance of resource leaks compared to manual try-finally blocks. This pattern is especially helpful for I/O operations or when dealing with external systems.

Example: Let’s say you’re reading a CSV file and want to ensure it’s closed properly, even if processing the file fails.

import csv

def read_csv_data(file_path):
    try:
        with open(file_path, 'r') as file:
            print(f"Inside 'with': file.closed = {file.closed}")  # Should be False
            reader = csv.reader(file)
            for row in reader:
                if len(row) 

 
This code uses a with statement (context manager) to safely open and read the file. If any row has fewer than 2 values, it raises a ValueError, but the file still gets closed automatically. The file.closed checks confirm the file’s state both inside and after the with block—even in case of an error. Let’s run the above code to observe this behavior:

Output:
Inside 'with': file.closed = False
['Name', 'Age']
['Sarwar', '30']
Error: Invalid row format
In except block: file is closed? True

 

3. Exception Wrapping for Contextual Errors

 
Sometimes, an exception in a lower-level function doesn’t provide enough context about what went wrong in the broader application. Exception wrapping (or chaining) lets you catch an exception, add context, and re-raise a new exception that includes the original one. It’s especially useful in layered applications (e.g., APIs or services).

Example: Suppose you’re fetching user data from a database and want to provide context when a database error occurs.

class DatabaseAccessError(Exception):
    """Raised when database operations fail."""
    pass

def fetch_user(user_id):
    try:
        # Simulate database query
        raise ConnectionError("Failed to connect to database")
    except ConnectionError as e:
        raise DatabaseAccessError(f"Failed to fetch user {user_id}") from e

try:
    fetch_user(123)
except DatabaseAccessError as e:
    print(f"Error: {e}")
    print(f"Caused by: {e.__cause__}")

 

The ConnectionError is caught and wrapped in a DatabaseAccessError with additional context about the user ID. The from e syntax links the original exception, so the full error chain is available for debugging. The output might look like this:

Output:
Error: Failed to fetch user 123
Caused by: Failed to connect to database

 

4. Retry Logic for Transient Failures

 
Some errors, like network timeouts or temporary service unavailability, are transient and may resolve on retry. Using a retry pattern can handle these gracefully without cluttering your code with manual loops. It automates recovery from temporary failures.

Example: Let’s retry a flaky API call that occasionally fails due to simulated network errors. The code below attempts the API call multiple times with a fixed delay between retries. If the call succeeds, it returns the result immediately. If all retries fail, it raises an exception to be handled by the caller.

import random
import time

def flaky_api_call():
    # Simulate 50% chance of failure (like timeout or server error)
    if random.random() 

 

Output:
Attempt 1 failed: Simulated network failure. Retrying in 2 seconds...
API call succeeded: {'status': 'success', 'data': [1, 2, 3]}

 
As you can see, the first attempt failed due to the simulated network error (which happens randomly 50% of the time). The retry logic waited for 2 seconds and then successfully completed the API call on the next attempt.

 

5. Custom Exception Classes for Domain-Specific Errors

 
Instead of relying on generic exceptions like ValueError or RuntimeError, you can create custom exception classes to represent specific errors in your application’s domain. This makes error handling more semantic and easier to maintain.

Example: Suppose a payment processing system where different types of payment failures need specific handling.

class PaymentError(Exception):
    """Base class for payment-related exceptions."""
    pass

class InsufficientFundsError(PaymentError):
    """Raised when the account has insufficient funds."""
    pass

class InvalidCardError(PaymentError):
    """Raised when the card details are invalid."""
    pass

def process_payment(amount, card_details):
    try:
        if amount > 1000:
            raise InsufficientFundsError("Not enough funds for this transaction")
        if not card_details.get("valid"):
            raise InvalidCardError("Invalid card details provided")
        print("Payment processed successfully")
    except InsufficientFundsError as e:
        print(f"Payment failed: {e}")
        # Notify user to top up account
    except InvalidCardError as e:
        print(f"Payment failed: {e}")
        # Prompt user to re-enter card details
    except Exception as e:
        print(f"Unexpected error: {e}")
        # Log for debugging

process_payment(1500, {"valid": False})

 

Custom exceptions (InsufficientFundsError, InvalidCardError) inherit from a base PaymentError class, allowing you to handle specific payment issues differently while catching unexpected errors with a generic Exception block. For example, In the call process_payment(1500, {“valid”: False}), the first check triggers because the amount (1500) exceeds 1000, so it raises InsufficientFundsError. This exception is caught in the corresponding except block, printing:

Output:
Payment failed: Not enough funds for this transaction

 

Conclusion

 
That’s it. In this article, we explored 5 practical error handling patterns:

  1. Error Aggregation: Process all items, collect errors, and report them together
  2. Context Manager: Safely manage resources like files with with blocks
  3. Exception Wrapping: Add context by catching and re-raising exceptions
  4. Retry Logic: Automatically retry transient errors like network failures
  5. Custom Exceptions: Create specific error classes for clearer handling

Give these patterns a try in your next project. With a bit of practice, you’ll find your code easier to maintain and your error handling much more effective.
 
 

Kanwal Mehreen Kanwal is a machine learning engineer and a technical writer with a profound passion for data science and the intersection of AI with medicine. She co-authored the ebook “Maximizing Productivity with ChatGPT”. As a Google Generation Scholar 2022 for APAC, she champions diversity and academic excellence. She’s also recognized as a Teradata Diversity in Tech Scholar, Mitacs Globalink Research Scholar, and Harvard WeCode Scholar. Kanwal is an ardent advocate for change, having founded FEMCodes to empower women in STEM fields.

Tags: errorHandlingPatternsPythonTryExcept
Previous Post

AI in Publishing: What Matters for an Ethical Future

Next Post

A Comprehensive Coding Tutorial for Advanced SerpAPI Integration with Google Gemini-1.5-Flash for Advanced Analytics

softbliss

softbliss

Related Posts

Introducing Veo and Imagen 3 generative AI tools
Machine Learning

Introducing Veo and Imagen 3 generative AI tools

by softbliss
June 7, 2025
How I Automated My Machine Learning Workflow with Just 10 Lines of Python
Machine Learning

How I Automated My Machine Learning Workflow with Just 10 Lines of Python

by softbliss
June 6, 2025
What It Is and Why It Matters—Part 3 – O’Reilly
Machine Learning

What It Is and Why It Matters—Part 3 – O’Reilly

by softbliss
June 6, 2025
New AI Innovation Hub in Tunisia Drives Technological Advancement Across Africa
Machine Learning

New AI Innovation Hub in Tunisia Drives Technological Advancement Across Africa

by softbliss
June 5, 2025
Machine Learning

Beyond Text Compression: Evaluating Tokenizers Across Scales

by softbliss
June 5, 2025
Next Post
A Comprehensive Coding Tutorial for Advanced SerpAPI Integration with Google Gemini-1.5-Flash for Advanced Analytics

A Comprehensive Coding Tutorial for Advanced SerpAPI Integration with Google Gemini-1.5-Flash for Advanced Analytics

Leave a Reply Cancel reply

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

Premium Content

Innovation for New Zero Concrete

March 24, 2025
Zoho shelves $700 M chipmaking plan, Sridhar Vembu unsure about tech

Zoho shelves $700 M chipmaking plan, Sridhar Vembu unsure about tech

May 2, 2025
14 Powerful Techniques Defining the Evolution of Embedding

14 Powerful Techniques Defining the Evolution of Embedding

May 2, 2025

Browse by Category

  • Artificial Intelligence
  • Machine Learning
  • Research & Academia
  • Software Development
  • Startups

Browse by Tags

Amazon App Artificial Blog Build Building Business Coding Data Development Digital Framework Future Gemini Generative Google Guide Impact Innovation Intelligence Key Language Large Learning LLM LLMs Machine Microsoft MIT model Models News NVIDIA opinion OReilly Research Science Series Software Startup Startups students Tech Tools Video

Soft Bliss Academy

Welcome to SoftBliss Academy, your go-to source for the latest news, insights, and resources on Artificial Intelligence (AI), Software Development, Machine Learning, Startups, and Research & Academia. We are passionate about exploring the ever-evolving world of technology and providing valuable content for developers, AI enthusiasts, entrepreneurs, and anyone interested in the future of innovation.

Categories

  • Artificial Intelligence
  • Machine Learning
  • Research & Academia
  • Software Development
  • Startups

Recent Posts

  • Emails Shed Light on UNC’s Plans to Create a New Accreditor
  • 3 Questions: How to help students recognize potential bias in their AI datasets | MIT News
  • Introducing Veo and Imagen 3 generative AI tools

© 2025 https://softblissacademy.online/- All Rights Reserved

No Result
View All Result
  • Home
  • Artificial Intelligence
  • Software Development
  • Machine Learning
  • Research & Academia
  • Startups

© 2025 https://softblissacademy.online/- All Rights Reserved

Are you sure want to unlock this post?
Unlock left : 0
Are you sure want to cancel subscription?