"""Structured error types for SafeSpace.""" from __future__ import annotations from typing import Any, Dict, Optional class SafeSpaceError(Exception): """Base error with a stable machine-readable code.""" def __init__( self, code: str, message: str, *, status_code: int = 400, context: Optional[Dict[str, Any]] = None, ) -> None: super().__init__(message) self.code = code self.message = message self.status_code = status_code self.context = context or {} def to_payload(self) -> Dict[str, Any]: """Serialize the error for HTTP or test assertions.""" return { "code": self.code, "message": self.message, "context": self.context, } class ScenarioCorpusError(SafeSpaceError): """Raised when the scenario corpus is missing or invalid.""" def __init__(self, message: str, *, context: Optional[Dict[str, Any]] = None) -> None: super().__init__( "scenario_corpus_invalid", message, status_code=500, context=context, ) class ScenarioLookupError(SafeSpaceError): """Raised when a requested task or scenario cannot be resolved.""" def __init__( self, code: str, message: str, *, context: Optional[Dict[str, Any]] = None, ) -> None: super().__init__(code, message, status_code=422, context=context)