← Master Index
Vol. 03 Module 3.4 Lecture

Exception Handling (try/except)

Essential Python Skills for AI Engineers (added — needed in practice, not in original outline)

How This Lesson Fits the Module

AI systems fail constantly—network timeouts, malformed JSON, CUDA OOM errors, missing files. Exception handling with try/except lets you recover gracefully, log context, and keep pipelines running instead of crashing silently or spewing stack traces to end users.

After decorators (often combined with retry logic), structured error handling is the next skill for production-grade inference services and data ingestion scripts.

Learning Objectives

By the end of this lesson, students should be able to:

  • Use try, except, else, and finally blocks correctly.
  • Catch specific exception types rather than bare except:.
  • Re-raise exceptions with raise while preserving context.
  • Define custom exception classes for domain errors.
  • Apply exception handling to API calls, file I/O, and model inference.
  • Distinguish when to fail fast versus when to retry or skip bad records.

Introduction: Controlled Failure

When Python encounters an error it cannot handle, it raises an exception. Uncaught exceptions terminate the program. A try block lets you intercept specific failures and decide what happens next.

Definition — try/except Structure
try:
    risky_operation()
except SpecificError as exc:
    handle(exc)
else:
  # runs only if no exception occurred
    ...
finally:
  # always runs (cleanup)
    ...
AI Example — Robust API Call
import requests

def fetch_embedding(text: str) -> list[float]:
    try:
        resp = requests.post(EMBED_URL, json={"text": text}, timeout=30)
        resp.raise_for_status()
        return resp.json()["embedding"]
    except requests.Timeout:
        raise RuntimeError(f"Embedding service timed out for: {text[:50]!r}")
    except requests.HTTPError as exc:
        raise RuntimeError(f"HTTP {exc.response.status_code}") from exc

Exception Hierarchy and Specificity

ExceptionTypical AI CauseHandling Strategy
FileNotFoundErrorMissing dataset or checkpointValidate paths at startup
json.JSONDecodeErrorMalformed API / JSONL lineSkip record, log line number
KeyErrorUnexpected response schemaSchema validation, fallbacks
torch.cuda.OutOfMemoryErrorBatch too largeReduce batch size, gradient checkpointing
ValueErrorInvalid hyperparametersFail fast with clear message
Common Misconception: “Catch everything with except Exception: and ignore it.”

Reality: Swallowing errors hides data corruption and training bugs. Catch specific types, log context, and either recover meaningfully or re-raise. Never use bare except: (it catches KeyboardInterrupt too).

Custom Exceptions

class ModelNotLoadedError(RuntimeError):
    """Raised when inference runs before model weights are loaded."""

def predict(text):
    if model is None:
        raise ModelNotLoadedError("Call load_model() first")
    ...

Knowledge Check

  1. True/False: finally runs even if return appears in try. Answer: True.
  2. Short Answer: Why catch requests.Timeout separately? Answer: Different recovery (retry/backoff) than HTTP errors.
  3. Multiple Choice: Best practice for unknown errors in production: (a) bare except pass, (b) log and re-raise or return error response, (c) restart Python silently, (d) delete data. Answer: (b).
  4. Short Answer: When does the else clause on try run? Answer: Only if no exception occurred in the try block.
  5. True/False: Bare except: is safe because it only catches application errors. Answer: False—it also catches KeyboardInterrupt; catch specific types instead.
  6. Short Answer: Typical handling for json.JSONDecodeError on a JSONL line? Answer: Skip the record and log the line number.
  7. Multiple Choice: CUDA OOM during training often suggests: (a) increase batch size, (b) reduce batch size / use checkpointing, (c) delete Python, (d) ignore it. Answer: (b).
  8. True/False: Custom exceptions like ModelNotLoadedError can clarify domain errors. Answer: True.
  9. Short Answer: Why re-raise with raise ... from exc? Answer: Preserve the original exception context for debugging.
  10. Multiple Choice: Invalid hyperparameters should usually: (a) fail fast with a clear message, (b) be silently clipped, (c) crash the OS, (d) skip logging. Answer: (a).

Key Takeaways

  • Use try/except to handle expected failure modes without crashing.
  • Catch specific exceptions; log context; avoid silent swallowing.
  • Custom exceptions clarify domain errors in AI services.
  • Next: File I/O, where many exceptions originate.
Trainer’s Guide

Failure injection: Provide a JSONL file with one bad line. Students write a loader that logs and skips bad rows instead of aborting the entire import.

Recap: Catch specific exceptions, log context, and fail or retry deliberately; next, persist data with File I/O (JSON, CSV, text).