Source code for ogu_api.errors

from __future__ import annotations

from typing import Any

__all__ = [
    'OGUError',
    'OGUAPIError',
    'OGUAuthenticationError',
    'OGUAuthorizationError',
    'OGUNotFoundError',
    'OGUValidationError',
    'OGURateLimitError',
    'OGUServerError',
    'OGUNetworkError',
    'OGUTimeoutError',
    'OGUParseError',
    'OGUSessionError',
    'OGULoginError',
    'OGUReputationError',
    'OGUCreditsError',
]


[docs] class OGUError(Exception): """Base class for every exception raised by ``ogu-api``. Catch this when you want to handle anything the SDK might throw. """
[docs] class OGUNetworkError(OGUError): """Network-level failure: connection refused, DNS error, TLS handshake, etc."""
[docs] class OGUTimeoutError(OGUNetworkError): """Request exceeded :attr:`HttpClientConfig.timeout_seconds`."""
[docs] class OGUAPIError(OGUError): """HTTP error response from the forum (4xx / 5xx). Subclassed by status-code-specific errors (``OGUNotFoundError``, etc.). The exact subclass is chosen by :class:`HttpClient` based on the status. Attributes: status_code: HTTP status code. method: HTTP method used (``'GET'``, ``'POST'``, …). url: Full URL of the failing request. body: Response body, if available, for inspection. """ def __init__( self, message: str, *, status_code: int, method: str, url: str, body: str | None = None, ) -> None: super().__init__(message) self.status_code: int = status_code self.method: str = method self.url: str = url self.body: str | None = body def __str__(self) -> str: base = super().__str__() return f'{base} [{self.method} {self.url} -> {self.status_code}]'
[docs] class OGUAuthenticationError(OGUAPIError): """HTTP 401: missing or invalid session cookie."""
[docs] class OGUAuthorizationError(OGUAPIError): """HTTP 403: session is valid but the action isn't permitted."""
[docs] class OGUNotFoundError(OGUAPIError): """HTTP 404: resource (profile, thread, page) not found."""
[docs] class OGUValidationError(OGUAPIError): """HTTP 400 / 422: form or query parameters were rejected."""
[docs] class OGURateLimitError(OGUAPIError): """HTTP 429: rate-limited by the forum or fronting CDN. Attributes: retry_after_seconds: ``Retry-After`` header value when present, else ``None``. The HTTP layer honors this automatically when retries are configured. """ def __init__( self, message: str, *, status_code: int, method: str, url: str, body: str | None = None, retry_after_seconds: float | None = None, ) -> None: super().__init__( message, status_code = status_code, method = method, url = url, body = body, ) self.retry_after_seconds: float | None = retry_after_seconds
[docs] class OGUServerError(OGUAPIError): """HTTP 5xx: forum or upstream returned a server error."""
[docs] class OGUParseError(OGUError): """A page came back, but expected HTML structure was missing. Raised when an extractor needed a specific element that wasn't present — e.g. profile pages without ``#profileLink``. """ def __init__(self, message: str = 'Failed to parse response') -> None: super().__init__(message)
[docs] class OGUSessionError(OGUError): """The session cookie is missing or has expired. Raised by helpers that depend on a logged-in session. """ def __init__(self, message: str = 'Session is invalid or expired') -> None: super().__init__(message)
[docs] class OGULoginError(OGUError): """Login flow returned an error indicator from the forum.""" def __init__(self, message: str = 'Login failed') -> None: super().__init__(message)
[docs] class OGUReputationError(OGUError): """The forum rejected a reputation submission. Most commonly raised when the value passed to :meth:`ReputationResource.send` isn't in the target user's allowed options. Attributes: valid_amounts: List of allowed reputation values returned by the target's modal, or ``None`` when not available. """ def __init__( self, message: str = 'Reputation request failed', *, valid_amounts: list[str] | None = None, ) -> None: super().__init__(message) self.valid_amounts: list[str] | None = valid_amounts
[docs] class OGUCreditsError(OGUError): """The forum rejected a credits transfer.""" def __init__(self, message: str = 'Credits request failed') -> None: super().__init__(message)