Source code for litestar.exceptions.responses

from __future__ import annotations

from dataclasses import asdict, dataclass, field
from typing import Any

from litestar import MediaType, Request, Response
from litestar.exceptions import HTTPException, LitestarException
from litestar.exceptions.responses import _debug_response
from litestar.serialization import encode_json, get_serializer
from litestar.status_codes import HTTP_500_INTERNAL_SERVER_ERROR

__all__ = (
    "ExceptionResponseContent",
    "create_debug_response",
    "create_exception_response",
)


[docs] @dataclass class ExceptionResponseContent: """Represent the contents of an exception-response.""" status_code: int """Exception status code.""" detail: str """Exception details or message.""" media_type: MediaType | str """Media type of the response.""" headers: dict[str, str] | None = field(default=None) """Headers to attach to the response.""" extra: dict[str, Any] | list[Any] | None = field(default=None) """An extra mapping to attach to the exception."""
[docs] def to_response(self, request: Request | None = None) -> Response: """Create a response from the model attributes. Returns: A response instance. """ content: Any = {k: v for k, v in asdict(self).items() if k not in ("headers", "media_type") and v is not None} type_encoders = _debug_response._get_type_encoders_for_request(request) if request is not None else None if self.media_type != MediaType.JSON: content = encode_json(content, get_serializer(type_encoders)) return Response( content=content, headers=self.headers, status_code=self.status_code, media_type=self.media_type, type_encoders=type_encoders, )
[docs] def create_exception_response(request: Request[Any, Any, Any], exc: Exception) -> Response: """Construct a response from an exception. Notes: - For instances of :class:`HTTPException <litestar.exceptions.HTTPException>` or other exception classes that have a ``status_code`` attribute (e.g. Starlette exceptions), the status code is drawn from the exception, otherwise response status is ``HTTP_500_INTERNAL_SERVER_ERROR``. Args: request: The request that triggered the exception. exc: An exception. Returns: Response: HTTP response constructed from exception details. """ headers: dict[str, Any] | None extra: dict[str, Any] | list | None if isinstance(exc, HTTPException): status_code = exc.status_code headers = exc.headers extra = exc.extra else: status_code = HTTP_500_INTERNAL_SERVER_ERROR headers = None extra = None detail = ( exc.detail if isinstance(exc, LitestarException) and status_code != HTTP_500_INTERNAL_SERVER_ERROR else "Internal Server Error" ) try: media_type = request.route_handler.media_type except (KeyError, AttributeError): media_type = MediaType.JSON content = ExceptionResponseContent( status_code=status_code, detail=detail, headers=headers, extra=extra, media_type=media_type, ) return content.to_response(request=request)
[docs] def create_debug_response(request: Request, exc: Exception) -> Response: """Create a debug response from an exception. Args: request: The request that triggered the exception. exc: An exception. Returns: Response: Debug response constructed from exception details. """ return _debug_response.create_debug_response(request, exc)