Phase 3 of 25 · Topic 3.4

Exception Groups & except* Syntax (Python 3.11+)

1Concept

Python 3.11 introduced `ExceptionGroup` and `except*` syntax (PEP 654) to handle multiple concurrent exceptions occurring simultaneously in asynchronous TaskGroups or multi-threaded worker pools.

2Architecture Diagram

ExceptionGroup("Task Failures", [ValueError("Bad ID"), TimeoutError("Network down")])
       |
       +---> except* ValueError:  Handles ValueError branch
       +---> except* TimeoutError: Handles TimeoutError branch

3Code Example

Python 3.12
try:
    raise ExceptionGroup(
        "Concurrent Batch Failures",
        [
            ValueError("Invalid Product SKU format"),
            ConnectionResetError("Redis connection drop"),
            ValueError("Negative price value")
        ]
    )
except* ValueError as eg:
    print(f"Handled {len(eg.exceptions)} ValueErrors: {[str(e) for e in eg.exceptions]}")
except* ConnectionResetError as eg:
    print(f"Handled Network Reset Error: {eg.exceptions[0]}")

4Expected Output

Handled 2 ValueErrors: ['Invalid Product SKU format', 'Negative price value']
Handled Network Reset Error: Redis connection drop

5Key Takeaways

  • `except*` matches and handles specific subsets of exceptions inside an ExceptionGroup.
  • Unmatched exceptions inside an ExceptionGroup are automatically re-raised.
  • Core foundation for Python 3.11+ structured concurrency with `asyncio.TaskGroup`.