Newer
Older
gn-synapse-client-py / src / gnexus_synapse / exceptions.py
"""Типизированные исключения клиента.

Каждый класс = одна ситуация, в которой сервису нужно разное поведение:
401 — ключ потерян/отозван (пересоздать), 403 — source в конверте не совпал
с источником ключа (анти-спуфинг, ошибка кода), 422 — конверт не принят
(ошибка кода или тип не зарегистрирован), 5xx — Synapse лежит, connection —
недоступен. `detail` — человекочитаемое сообщение, `status_code` — HTTP-код,
если был ответ.
"""

from __future__ import annotations


class SynapseError(RuntimeError):
    """База: всё, что клиент бросает, ловится этим классом."""

    def __init__(self, detail: str, *, status_code: int | None = None) -> None:
        super().__init__(detail)
        self.detail = detail
        self.status_code = status_code


class SynapseConfigError(SynapseError):
    """Нет url/api_key в аргументах и env, или конфиг в принципе битый."""


class SynapseConnectionError(SynapseError):
    """HTTP-транспорт недоступен (DNS, refusal, timeout). __cause__ — оригинал."""


class SynapseAuthError(SynapseError):
    """401: ключ отсутствует, неизвестен или отозван (источник архива — тоже сюда)."""


class SynapseForbiddenError(SynapseError):
    """403: поле source в конверте не совпадает с источником ключа."""


class SynapseNotFoundError(SynapseError):
    """404: событие с таким id у источника ключа не найдено."""


class SynapseValidationError(SynapseError):
    """422 от сервера ИЛИ локальная ошибка конверта (status_code=None)."""


class SynapseServerError(SynapseError):
    """5xx: Synapse недоступен/ошибка на его стороне — сообщение не ушло."""


class SynapseWebhookError(SynapseError):
    """s2s-доставка не прошла проверку: нет/битый заголовок подписи,
    чужой секрет, replay (тело старше окна свежести), не-JSON тело.
    Локальная ошибка приёма (status_code=None) — это не про отправку."""


class SynapseStatusTimeoutError(SynapseError):
    """wait_for_status: событие не достигло целевого статуса за timeout.
    Для приёмочных тестов/диагностики, не бизнес-обещаний."""