Skip to content

Commit

Permalink
feat: Raise exception when body parameter is annotated with non-bytes…
Browse files Browse the repository at this point in the history
… type (#3740)
  • Loading branch information
provinzkraut authored Sep 15, 2024
1 parent d4ff8e7 commit ec2fb0b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
7 changes: 7 additions & 0 deletions litestar/handlers/http_handlers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,5 +599,12 @@ def _validate_handler_function(self) -> None:
if "data" in self.parsed_fn_signature.parameters and "GET" in self.http_methods:
raise ImproperlyConfiguredException("'data' kwarg is unsupported for 'GET' request handlers")

if (body_param := self.parsed_fn_signature.parameters.get("body")) and not body_param.is_subclass_of(bytes):
raise ImproperlyConfiguredException(
f"Invalid type annotation for 'body' parameter in route handler {self}. 'body' will always receive the "
f"raw request body as bytes but was annotated with '{body_param.raw!r}'. If you want to receive "
"processed request data, use the 'data' parameter."
)


route = HTTPRouteHandler
25 changes: 23 additions & 2 deletions tests/unit/test_handlers/test_http_handlers/test_validations.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from pathlib import Path
from types import ModuleType
from typing import Callable, Dict
from typing import Any, Callable, Dict, List

import pytest
from typing_extensions import Annotated

from litestar import HttpMethod, Litestar, WebSocket, delete, get, route
from litestar import HttpMethod, Litestar, WebSocket, delete, get, patch, post, put, route
from litestar.exceptions import ImproperlyConfiguredException, ValidationException
from litestar.handlers.http_handlers import HTTPRouteHandler
from litestar.params import Body
from litestar.response import File, Redirect
from litestar.status_codes import (
HTTP_100_CONTINUE,
Expand Down Expand Up @@ -144,3 +146,22 @@ def no_response_handler() -> {return_annotation}:
return

Litestar(route_handlers=[module.no_response_handler])


@pytest.mark.parametrize("decorator", [post, put, patch])
def test_body_param_with_non_bytes_annotation_raises(decorator: Callable[..., Any]) -> None:
def handler_fn(body: List[str]) -> None:
pass

with pytest.raises(ImproperlyConfiguredException, match="Invalid type annotation for 'body' parameter"):
Litestar([decorator()(handler_fn)])


@pytest.mark.parametrize("decorator", [post, put, patch])
def test_body_param_with_metadata_allowed(decorator: Callable[..., Any]) -> None:
def handler_fn(body: Annotated[bytes, Body(title="something")]) -> None:
pass

# we expect no error here, even though the type isn't directly 'bytes' but has
# metadata attached to it
Litestar([decorator()(handler_fn)])

0 comments on commit ec2fb0b

Please sign in to comment.