Exception Policy

ServiceError subclasses: Become RuntimeInfo(status=”error”, code=…, message=…)

  • Used for expected failure modes (not found, invalid state, etc.)

  • CLI catches and displays nicely

  • REST maps to appropriate HTTP status + RuntimeInfo body

Other exceptions: True bugs/unexpected conditions

  • ValueError, TypeError, etc. from bad code

  • CLI lets them bubble (traceback helps debug)

  • REST catches as 500 + generic error RuntimeInfo

Usage

# In controller
if choice_id not in available:
    raise InvalidOperationError(f"Choice {choice_id} not available")

# NOT this:
if choice_id not in available:
    return RuntimeInfo(status="error", code="INVALID_CHOICE", ...)

Rationale

Exceptions allow early exit and cleaner control flow. The orchestrator and transport layers decide how to present them to users.