"""Typed errors raised by the scopone engine. Route/WebSocket handlers translate these into 4xx responses or ``error`` WebSocket messages; the engine itself stays transport-agnostic. """ from __future__ import annotations class GameError(Exception): """Base class for every rule/validation failure.""" class IllegalMove(GameError): """The requested play violates the rules of scopone scientifico.""" class NotYourTurn(GameError): """A player attempted to play out of turn.""" class CardNotInHand(GameError): """The played card is not held by the player.""" class GameNotStarted(GameError): """An action was attempted before the game left the lobby.""" class GameFinished(GameError): """An action was attempted after the match ended.""" class LobbyFull(GameError): """A game already has four players.""" class AlreadyJoined(GameError): """A player tried to join a game they are already seated in.""" class GameNotFound(GameError): """No live game exists for the given id or join code."""