diff --git a/connexion/validators/form_data.py b/connexion/validators/form_data.py index 327a23f43..c647b0c93 100644 --- a/connexion/validators/form_data.py +++ b/connexion/validators/form_data.py @@ -70,12 +70,13 @@ async def _parse(self, stream: t.AsyncGenerator[bytes, None], scope: Scope) -> d return data - def _validate(self, data: dict) -> None: + def _validate(self, body: t.Any) -> t.Optional[dict]: # type: ignore[return] + if not isinstance(body, dict): + raise BadRequestProblem("Parsed body must be a mapping") if self._strict_validation: - self._validate_params_strictly(data) - + self._validate_params_strictly(body) try: - self._validator.validate(data) + self._validator.validate(body) except ValidationError as exception: error_path_msg = format_error_with_path(exception=exception) logger.error( diff --git a/connexion/validators/json.py b/connexion/validators/json.py index 77753f4d2..5babce5ff 100644 --- a/connexion/validators/json.py +++ b/connexion/validators/json.py @@ -61,7 +61,9 @@ async def _parse( except json.decoder.JSONDecodeError as e: raise BadRequestProblem(detail=str(e)) - def _validate(self, body: dict) -> None: + def _validate(self, body: t.Any) -> t.Optional[dict]: + if not self._nullable and body is None: + raise BadRequestProblem("Request body must not be empty") try: return self._validator.validate(body) except ValidationError as exception: diff --git a/tests/api/test_errors.py b/tests/api/test_errors.py index 00445f280..7c4e31ea7 100644 --- a/tests/api/test_errors.py +++ b/tests/api/test_errors.py @@ -88,3 +88,10 @@ def test_errors(problem_app): "Invalid Content-type (text/html)" ) assert unsupported_media_type_body["status"] == 415 + + +def test_should_raise_400_for_no_json(simple_app): + app_client = simple_app.test_client() + response = app_client.post("/v1.0/test-empty-object-body") + assert response.status_code == 400 + assert response.json()["detail"] == "Request body must not be empty"