Skip to content

Reactive Routes: malformed JSON in a @Body parameter results in 500 instead of 400 #57824

Open

Description

@pschaub

Describe the bug

A reactive route with a @Body parameter of type JsonObject, JsonArray or a POJO returns 500 Internal Server Error when the request body is malformed JSON. The generated handler calls RequestBody.asJsonObject() / asJsonArray() (ReactiveRoutesProcessor). The resulting DecodeException is not handled and ends up in QuarkusErrorHandler.

Expected behavior

400 Bad Request, as Quarkus REST returns for the same request.

Actual behavior

500 Internal Server Error, with these log entries:

ERROR [io.quarkus.vertx.http.runtime.QuarkusErrorHandler] (vert.x-eventloop-thread-1) HTTP Request to /object failed, error id: ...: io.vertx.core.json.DecodeException: Failed to decode:Unexpected end-of-input within/between Object entries
ERROR [io.quarkus.vertx.http.runtime.QuarkusErrorHandler] (vert.x-eventloop-thread-0) HTTP Request to /pojo failed, error id: ...: io.vertx.core.json.DecodeException: Failed to decode:Unexpected end-of-input within/between Object entries

How to Reproduce?

  1. Create a project:
    mvn io.quarkus.platform:quarkus-maven-plugin:3.40.1.1:create \
        -DprojectGroupId=org.acme -DprojectArtifactId=reactive-routes-repro \
        -Dextensions=reactive-routes -DnoCode
    cd reactive-routes-repro
  2. Add src/main/java/org/acme/Routes.java:
    package org.acme;
    
    import io.quarkus.vertx.web.Body;
    import io.quarkus.vertx.web.Route;
    import io.quarkus.vertx.web.Route.HttpMethod;
    import io.vertx.core.json.JsonObject;
    
    public class Routes {
    
        public static class Person {
            public String name;
        }
    
        @Route(path = "/object", methods = HttpMethod.POST)
        String object(@Body JsonObject body) {
            return "ok";
        }
    
        @Route(path = "/pojo", methods = HttpMethod.POST)
        String pojo(@Body Person body) {
            return "ok";
        }
    }
  3. Run ./mvnw quarkus:dev.
  4. Send requests:
    curl -s -o /dev/null -w "%{http_code}\n" -X POST localhost:8080/object -H 'Content-Type: application/json' -d '{"name": "foo"}'   # 200
    curl -s -o /dev/null -w "%{http_code}\n" -X POST localhost:8080/pojo   -H 'Content-Type: application/json' -d '{"name": "foo"}'   # 200
    curl -s -o /dev/null -w "%{http_code}\n" -X POST localhost:8080/object -H 'Content-Type: application/json' -d '{"name": '          # 500
    curl -s -o /dev/null -w "%{http_code}\n" -X POST localhost:8080/pojo   -H 'Content-Type: application/json' -d '{"name": '          # 500

The same result with 4.0.0.Beta1 instead of 3.40.1.1 in step 1.

Output of uname -a or ver

Linux 6.18.54.1-microsoft-standard-WSL2 x86_64 GNU/Linux

Output of java -version

OpenJDK 21.0.12.1 (Temurin-21.0.12.1+1)

Quarkus version or git rev

3.40.1.1, 4.0.0.Beta1, main (5e98984)

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.9.9

Additional information

A possible fix: small helpers in RouteHandlers that turn the DecodeException into HttpException(400), called by the generated code instead of asJsonObject() / asJsonArray(). I have a patch with a test and am happy to open a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions