Source code for somerandomapi.errors

from __future__ import annotations

from typing import TYPE_CHECKING, Any
import contextlib

from . import utils as _utils

if TYPE_CHECKING:
    from .internals.endpoints import Endpoint
    from .models.abc import BaseModel


__all__ = (
    "BadRequest",
    "Forbidden",
    "HTTPException",
    "ImageError",
    "InternalServerError",
    "NotFound",
    "RateLimited",
    "SomeRandomApiException",
    "TypingError",
)


[docs] class SomeRandomApiException(Exception): """Base exception for all errors raised by this library. Attributes ---------- data: Any The data returned by the API. endpoint: ``Endpoint`` The endpoint that was called. Use ``endpoint.path`` to get the full path of the endpoint. """ def __init__(self, endpoint: Endpoint, data: Any, /) -> None: self.data: Any = data self.endpoint: Endpoint = endpoint self.message = f"{data!s}" if isinstance(data, dict): with contextlib.suppress(KeyError): self.message = data["error"] try: self.code = data["code"] except KeyError: self.code = getattr(self.__class__, "code", 0) self.message += f" (Code: {self.code})" super().__init__(f"While requesting /{endpoint.path}: {self.message}")
[docs] class BadRequest(SomeRandomApiException): """``Bad Request`` error.""" code = 400
[docs] class NotFound(SomeRandomApiException): """``Not Found`` error.""" code = 404
[docs] class InternalServerError(SomeRandomApiException): """``Internal Server Error`` error.""" def __init__(self, enum, data: Any, /) -> None: Exception.__init__(self, f"Internal Server Error while requesting {enum.base()}{enum.value.path}.")
[docs] class Forbidden(SomeRandomApiException): """``Forbidden`` error.""" code = 403
[docs] class RateLimited(SomeRandomApiException): """``Too Many Requests`` error.""" code = 429
[docs] class HTTPException(SomeRandomApiException): """Exception raised when an HTTP request fails.""" response: Any data: Any message: str code: int def __init__(self, enum, response, data: Any, /) -> None: self.response = response self.data = data if isinstance(data, dict): with contextlib.suppress(KeyError): self.message = data["error"] try: self.code = data["code"] except KeyError: self.code = response.status else: self.message = str(data) self.code = response.status super().__init__(enum, data)
[docs] class ImageError(SomeRandomApiException): """Exception raised when an image could not be retrieved. Attributes ---------- url: str The URL of the image. status: int The status code of the response. """ def __init__(self, url: str, status: int, /) -> None: self.url: str = url self.status: int = status Exception.__init__(self, f"Could not get image from {url} (code: {status})")
[docs] class TypingError(TypeError): """Exception raised when a typing error occurs. This is usually raised in a dataclass when a type is not what it is supposed to be. Attributes ---------- cls: ``BaseModel`` The class that the error occurred in. attribute: :class:`Attribute` The attribute that the error occurred in. Use ``attribute.name`` to get the name of the attribute (argument). """ def __init__( self, cls: BaseModel, attribute: Any, value: Any, *, message: str | None = None, cast_type: bool = True, **format_kwarg: Any, ) -> None: self.cls: BaseModel = cls self.attribute: Any = attribute message = message or "{field_name} must be of type {field_type} not {current_type}." field_value_type = type(value) if cast_type else value message = message.format( field_name=f"'{attribute.name}'", class_name=f"{cls.__class__.__name__}()", field_type=_utils._get_type(attribute.type, {}, {})[0], current_type=type(value).__name__, field_value=value, field_value_type=repr(field_value_type), **format_kwarg, ) self.error_message: str = message super().__init__(f"Error in class: {cls.__class__.__name__}() and argument: '{attribute.name}': {message}")