From fb3e87d0369b1567b0f86f19fb6aa0e98b6013c9 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Wed, 24 Feb 2021 17:02:29 +0200 Subject: [PATCH] Treat MismatchedInputException as client error in RESTEasy Reactive The Javadoc of MismatchedInputException even mentions that these exceptions should be treated as client exceptions Relates to: #15302 --- .../deployment/test/ExceptionInReaderTest.java | 4 +--- .../serialisers/JacksonMessageBodyReader.java | 11 +++++++++-- .../server/core/ResteasyReactiveRequestContext.java | 13 +++++++++++++ .../reactive/server/spi/ServerRequestContext.java | 3 +++ 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/ExceptionInReaderTest.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/ExceptionInReaderTest.java index 88064e308895e..f2beddab345e0 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/ExceptionInReaderTest.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/ExceptionInReaderTest.java @@ -1,7 +1,5 @@ package io.quarkus.resteasy.reactive.jackson.deployment.test; -import static org.hamcrest.CoreMatchers.containsString; - import java.util.function.Supplier; import org.jboss.shrinkwrap.api.ShrinkWrap; @@ -27,6 +25,6 @@ public JavaArchive get() { @Test public void test() { RestAssured.with().contentType("application/json").body("{\"name\": \"brie\"}").put("/fromage") - .then().statusCode(500).body(containsString("MismatchedInputException")); + .then().statusCode(400); } } diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/JacksonMessageBodyReader.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/JacksonMessageBodyReader.java index 657dca50a20f0..99248389396f4 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/JacksonMessageBodyReader.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/JacksonMessageBodyReader.java @@ -9,6 +9,7 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; import org.jboss.resteasy.reactive.common.util.EmptyInputStream; import org.jboss.resteasy.reactive.server.providers.serialisers.json.AbstractJsonMessageBodyReader; @@ -16,6 +17,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.exc.MismatchedInputException; public class JacksonMessageBodyReader extends AbstractJsonMessageBodyReader { @@ -29,13 +31,18 @@ public JacksonMessageBodyReader(ObjectMapper mapper) { @Override public Object readFrom(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, InputStream entityStream) throws IOException, WebApplicationException { - return doReadFrom(type, genericType, entityStream); + throw new IllegalStateException("Should never be called"); } @Override public Object readFrom(Class type, Type genericType, MediaType mediaType, ServerRequestContext context) throws WebApplicationException, IOException { - return doReadFrom(type, genericType, context.getInputStream()); + try { + return doReadFrom(type, genericType, context.getInputStream()); + } catch (MismatchedInputException e) { + context.abortWith(Response.status(Response.Status.BAD_REQUEST).build()); + return null; + } } private Object doReadFrom(Class type, Type genericType, InputStream entityStream) throws IOException { diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ResteasyReactiveRequestContext.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ResteasyReactiveRequestContext.java index 4b39cb279218d..dd8d3106ac44d 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ResteasyReactiveRequestContext.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ResteasyReactiveRequestContext.java @@ -178,6 +178,19 @@ public void restart(RuntimeResource target, boolean setLocatorTarget) { this.target = target; } + /** + * Meant to be used when a error occurred early in processing chain + */ + @Override + public void abortWith(Response response) { + setResult(response); + restart(getAbortHandlerChain()); + // this is a valid action after suspend, in which case we must resume + if (isSuspended()) { + resume(); + } + } + /** * Resets the build time serialization assumptions. Called if a filter * modifies the response diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/spi/ServerRequestContext.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/spi/ServerRequestContext.java index f4e0df4ea4a76..f0f0d51cd21dc 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/spi/ServerRequestContext.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/spi/ServerRequestContext.java @@ -3,6 +3,7 @@ import java.io.InputStream; import java.io.OutputStream; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import org.jboss.resteasy.reactive.common.core.ResteasyReactiveCallbackContext; public interface ServerRequestContext extends ResteasyReactiveCallbackContext { @@ -18,4 +19,6 @@ public interface ServerRequestContext extends ResteasyReactiveCallbackContext { OutputStream getOrCreateOutputStream(); ResteasyReactiveResourceInfo getResteasyReactiveResourceInfo(); + + void abortWith(Response response); }