Source code for litestar.exceptions.http_exceptions

from __future__ import annotations

from http import HTTPStatus
from typing import Any

from litestar.exceptions.base_exceptions import LitestarException
from litestar.status_codes import (
    HTTP_400_BAD_REQUEST,
    HTTP_401_UNAUTHORIZED,
    HTTP_403_FORBIDDEN,
    HTTP_404_NOT_FOUND,
    HTTP_405_METHOD_NOT_ALLOWED,
    HTTP_413_REQUEST_ENTITY_TOO_LARGE,
    HTTP_429_TOO_MANY_REQUESTS,
    HTTP_500_INTERNAL_SERVER_ERROR,
    HTTP_503_SERVICE_UNAVAILABLE,
)
from litestar.types.empty import Empty, EmptyType

__all__ = (
    "ClientException",
    "HTTPException",
    "ImproperlyConfiguredException",
    "InternalServerException",
    "MethodNotAllowedException",
    "NoRouteMatchFoundException",
    "NotAuthorizedException",
    "NotFoundException",
    "PermissionDeniedException",
    "ServiceUnavailableException",
    "TemplateNotFoundException",
    "TooManyRequestsException",
    "ValidationException",
)


[docs] class HTTPException(LitestarException): """Base exception for HTTP error responses. These exceptions carry information to construct an HTTP response. """ status_code: int = HTTP_500_INTERNAL_SERVER_ERROR """Exception status code.""" detail: str """Exception details or message.""" headers: dict[str, str] | None = None """Headers to attach to the response.""" extra: dict[str, Any] | list[Any] | None = None """An extra mapping to attach to the exception."""
[docs] def __init__( self, *args: Any, detail: str = "", status_code: int | None = None, headers: dict[str, str] | None | EmptyType = Empty, extra: dict[str, Any] | list[Any] | None | EmptyType = Empty, ) -> None: """Initialize ``HTTPException``. Set ``detail`` and ``args`` if not provided. Args: *args: if ``detail`` kwarg not provided, first arg should be error detail. detail: Exception details or message. Will default to args[0] if not provided. status_code: Exception HTTP status code. headers: Headers to set on the response. Defaults to the class's ``headers`` if not provided. Set to ``None`` explicitly to unset the default. extra: An extra mapping to attach to the exception. Defaults to the class's ``extra`` if not provided. Set to ``None`` explicitly to unset the default. """ super().__init__(*args, detail=detail) self.status_code = status_code or self.status_code self.extra = extra if extra is not Empty else self.extra self.headers = headers if headers is not Empty else self.headers if not self.detail: self.detail = HTTPStatus(self.status_code).phrase self.args = (f"{self.status_code}: {self.detail}", *self.args)
def __repr__(self) -> str: return f"{self.status_code} - {self.__class__.__name__} - {self.detail}" def __str__(self) -> str: return " ".join(self.args).strip()
[docs] class ImproperlyConfiguredException(HTTPException, ValueError): """Application has improper configuration."""
[docs] class ClientException(HTTPException): """Client error.""" status_code: int = HTTP_400_BAD_REQUEST
[docs] class ValidationException(ClientException, ValueError): """Client data validation error."""
[docs] class NotAuthorizedException(ClientException): """Request lacks valid authentication credentials for the requested resource.""" status_code = HTTP_401_UNAUTHORIZED
[docs] class PermissionDeniedException(ClientException): """Request understood, but not authorized.""" status_code = HTTP_403_FORBIDDEN
[docs] class NotFoundException(ClientException, ValueError): """Cannot find the requested resource.""" status_code = HTTP_404_NOT_FOUND
[docs] class MethodNotAllowedException(ClientException): """Server knows the request method, but the target resource doesn't support this method.""" status_code = HTTP_405_METHOD_NOT_ALLOWED
class RequestEntityTooLarge(ClientException): status_code = HTTP_413_REQUEST_ENTITY_TOO_LARGE detail = "Request Entity Too Large"
[docs] class TooManyRequestsException(ClientException): """Request limits have been exceeded.""" status_code = HTTP_429_TOO_MANY_REQUESTS
[docs] class InternalServerException(HTTPException): """Server encountered an unexpected condition that prevented it from fulfilling the request.""" status_code: int = HTTP_500_INTERNAL_SERVER_ERROR
[docs] class ServiceUnavailableException(InternalServerException): """Server is not ready to handle the request.""" status_code = HTTP_503_SERVICE_UNAVAILABLE
[docs] class NoRouteMatchFoundException(InternalServerException): """A route with the given name could not be found."""
[docs] class TemplateNotFoundException(InternalServerException): """Referenced template could not be found."""
[docs] def __init__(self, *args: Any, template_name: str) -> None: """Initialize ``TemplateNotFoundException``. Args: *args (Any): Passed through to ``super().__init__()`` - should not include ``detail``. template_name (str): Name of template that could not be found. """ super().__init__(*args, detail=f"Template {template_name} not found.")