Skip to main content

Featured

Google I/O 2026: Decoding WebMCP, Gemini 3.5 Flash & The Antigravity Runtime

Google I/O 2026: Decoding WebMCP, Gemini 3.5 Flash & The Antigravity Runtime

Skip to main content AI ARCHITECTURE MASTERY Google I/O Unpacked — WebMCP, Gemini 3.5 Flash & Antigravity ⏱️  5  min read Series: Logic & Legacy Level: Senior Architecture ⏳ Context: Google I/O just finished. As usual, it was full of flashing lights, loud music, and big promises. But as backend developers, we do not care about the stage show. We care about the code. Today, we are going to look closely at the three biggest announcements: WebMCP, Gemini 3.5 Flash, and the mysterious "Antigravity" project. We will separate the real API changes from the marketing hype. Rule #1: Ignore the Marketing, Look at the API Every big tech company wants you to think their new tool is magic. They use words like "revolutionary" and "zero-latency." But computers are not magic. They are just servers processing text. When Google announces something new, we have to look at the docume...

Python Exception Handling — Fault Tolerance & Custom Hierarchies (2026)

Skip to main content

Day 24: Fault Tolerance — Exception Hierarchies & Custom Domains

  • Series: Logic & Legacy
  • Day 24 / 30
  • Level: Senior Architecture

Context: We have connected to raw sockets and streamed our logs. But what happens when the network drops mid-connection? What happens when a JSON payload is missing a critical key? A crashed system is a tragedy; a silently failing system is a liability. Today, we architect Python fault tolerance.

"Pokemon Exception Handling: Gotta Catch 'Em All"

The most dangerous code in a junior developer's repository—the "Silent Killer"—looks like this:

The Architectural Anti-Pattern
try:
    do_something_complex()
except Exception as e:
    # Catching literally everything and swallowing the traceback
    print("Something went wrong.")

This is a cardinal architectural sin. It swallows tracebacks, hides critical syntax errors, and forces the application to limp forward in a corrupted state. Senior Architects do not suppress errors; they manage them with surgical precision through granular exception handling.

1. The Hierarchy of Failure (BaseException vs Exception)

In Python, exceptions are objects following a strict inheritance tree. At the root of this universe sits BaseException.

2. The Top 10 Core Exceptions

Infographic categorizing 10 common Python errors into Data Structure Faults, Integrity Faults, Environmental Faults, and Architectural Faults.

Data Structure & Integrity Faults

  • KeyError: Dictionary lookup failed. Fix: Use .get().
  • IndexError: List/Tuple index out of mathematical bounds.
  • TypeError: Invalid operation on a specific type (e.g., "string" + 5).
  • ValueError: Right type, but logically invalid value (e.g., int("ABC")).

Environmental & Architectural Faults

  • FileNotFoundError: OS-level physical disk failure.
  • ImportError: Module not found in sys.path. Usually a virtual env issue.
  • AttributeError: Calling a method the object doesn't possess.
  • ZeroDivisionError: Dividing by zero.
  • RecursionError: Physical stack frame exhaustion (Depth > 1000).

3. The Anatomy of a Rescue (try / except / else / finally)

Technical flow diagram illustrating the try-except-else-finally execution path.
Mastering the Try-Except-Else-Finally Flowchart

Shoving 50 lines of code into a try block is a massive anti-pattern. If you put everything inside, you risk catching an unrelated error by mistake, masking the bug. We use the else block to separate "dangerous I/O" from "safe processing."

The Complete Execution Gate
def read_and_process_data(filepath: str):
    try:
        # 1. DANGER ZONE: Minimal code that might fail
        file = open(filepath, 'r')
        data = file.read()
    except FileNotFoundError:
        # 2. THE RESCUE
        logger.error("Missing file")
        return None
    else:
        # 3. SAFE ZONE: Runs ONLY if the try block succeeded.
        return process_json(data)
    finally:
        # 4. THE GUARANTEE: Always runs (cleanup)
        # Better: Use Context Managers (the 'with' statement)
        pass

4. Architecting Custom Domain Exceptions

A senior developer doesn't raise ValueError("Insufficient funds"). That forces your API layer to parse strings to understand the failure. Instead, we architect Domain Exceptions.

Structured Domain Exceptions
class BillingError(Exception): pass

class InsufficientFundsError(BillingError):
    def __init__(self, user_id: int, deficit: float):
        self.user_id = user_id
        self.deficit = deficit
        super().__init__(f"User {user_id} short by ${deficit}")

5. Traceback Preservation: Exception Chaining

When translating a low-level error (like KeyError) to a high-level one (like UserNotFoundError), you must preserve the evidence. Using raise ... from ensures the original crash site is visible in your logs.

try:
    return db[user_id]
except KeyError as e:
    raise UserNotFoundError(user_id) from e

🛠️ Day 24 Project: The Domain Fault Matrix

  • Create a custom DataIngestionError hierarchy.
  • Implement a try/except/else block that parses JSON and chains JSONDecodeError into your custom domain error.
🔥 PRO UPGRADE: THE RETRY DECORATOR

Your challenge: Write a custom Python @retry decorator. It should accept a tuple of Exceptions and a tries count. If the function fails, it should catch the error, wait 1 second, and retry until it succeeds or runs out of attempts.

6. FAQ: Exception Architecture

EAFP vs. LBYL: Which is better for performance?

Python favors EAFP (Easier to Ask for Forgiveness than Permission). Instead of checking if 'key' in dict (LBYL), you just try to access it and catch the error. EAFP is generally faster in Python because it avoids a double-lookup in the dictionary if the key exists 99% of the time.

What are ExceptionGroups in Python 3.11+?

In async applications, multiple tasks might fail simultaneously. ExceptionGroup allows you to raise and catch multiple unrelated exceptions at once, ensuring no crash is lost in a concurrent flow.

Is using the `pass` keyword in an except block bad?

Swallowing an error with pass is dangerous. It should only be used if the failure is truly "ignorable" and you've added a comment explaining *why* it doesn't matter. Otherwise, it creates a black hole for bugs.

Comments