diff --git a/http/rest-client-reactive/pom.xml b/http/rest-client-reactive/pom.xml
index 36453b468..dc07b8595 100644
--- a/http/rest-client-reactive/pom.xml
+++ b/http/rest-client-reactive/pom.xml
@@ -31,5 +31,15 @@
org.apache.commons
commons-lang3
+
+ org.wiremock
+ wiremock
+ 3.2.0
+ test
+
+
+ io.quarkus
+ quarkus-smallrye-fault-tolerance
+
diff --git a/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/MalformedClient.java b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/MalformedClient.java
new file mode 100644
index 000000000..6a6e286e0
--- /dev/null
+++ b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/MalformedClient.java
@@ -0,0 +1,24 @@
+package io.quarkus.ts.http.restclient.reactive;
+
+import static java.time.temporal.ChronoUnit.SECONDS;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+
+import org.eclipse.microprofile.faulttolerance.Timeout;
+import org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders;
+import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
+
+@RegisterRestClient
+@Path("/malformed")
+@RegisterClientHeaders
+@Timeout(value = 5, unit = SECONDS)
+public interface MalformedClient {
+
+ @GET
+ @Path("/")
+ @Produces(MediaType.APPLICATION_JSON)
+ String get();
+}
diff --git a/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/resources/MalformedClientResource.java b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/resources/MalformedClientResource.java
new file mode 100644
index 000000000..97a788a7a
--- /dev/null
+++ b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/resources/MalformedClientResource.java
@@ -0,0 +1,26 @@
+package io.quarkus.ts.http.restclient.reactive.resources;
+
+import jakarta.inject.Inject;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+
+import org.eclipse.microprofile.rest.client.inject.RestClient;
+
+import io.quarkus.ts.http.restclient.reactive.MalformedClient;
+
+@Path("/client/malformed")
+public class MalformedClientResource {
+ @Inject
+ @RestClient
+ MalformedClient client;
+
+ @GET
+ @Path("/")
+ public String getMalformed() {
+ try {
+ return client.get();
+ } catch (Exception ex) {
+ return ex.getClass().getName();
+ }
+ }
+}
diff --git a/http/rest-client-reactive/src/main/resources/modern.properties b/http/rest-client-reactive/src/main/resources/modern.properties
index 4f9f899f6..f549a895c 100644
--- a/http/rest-client-reactive/src/main/resources/modern.properties
+++ b/http/rest-client-reactive/src/main/resources/modern.properties
@@ -4,6 +4,7 @@ quarkus.rest-client."io.quarkus.ts.http.restclient.reactive.files.FileClient".ur
quarkus.rest-client."io.quarkus.ts.http.restclient.reactive.BookClient".url=http://localhost:${quarkus.http.port}
quarkus.rest-client."io.quarkus.ts.http.restclient.reactive.BookClient.AuthorClient".url=http://localhost:${quarkus.http.port}
quarkus.rest-client."io.quarkus.ts.http.restclient.reactive.ResourceAndSubResourcesClient".url=http://localhost:${quarkus.http.port}
+quarkus.rest-client."io.quarkus.ts.http.restclient.reactive.MalformedClient".url=http://localhost:${quarkus.http.port}
quarkus.rest-client.logging.scope=request-response
quarkus.log.category."org.jboss.resteasy.reactive.client.logging".level=DEBUG
diff --git a/http/rest-client-reactive/src/test/java/io/quarkus/ts/http/restclient/reactive/ReactiveRestClientIT.java b/http/rest-client-reactive/src/test/java/io/quarkus/ts/http/restclient/reactive/ReactiveRestClientIT.java
index 97e104322..d156121c1 100644
--- a/http/rest-client-reactive/src/test/java/io/quarkus/ts/http/restclient/reactive/ReactiveRestClientIT.java
+++ b/http/rest-client-reactive/src/test/java/io/quarkus/ts/http/restclient/reactive/ReactiveRestClientIT.java
@@ -1,5 +1,6 @@
package io.quarkus.ts.http.restclient.reactive;
+import static com.github.tomakehurst.wiremock.core.Options.ChunkedEncodingPolicy.NEVER;
import static io.quarkus.ts.http.restclient.reactive.resources.PlainBookResource.SEARCH_TERM_VAL;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
@@ -8,9 +9,16 @@
import java.util.UUID;
import org.apache.http.HttpStatus;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
+import com.github.tomakehurst.wiremock.WireMockServer;
+import com.github.tomakehurst.wiremock.client.WireMock;
+import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
+import com.github.tomakehurst.wiremock.http.Fault;
+
import io.quarkus.test.bootstrap.Protocol;
import io.quarkus.test.bootstrap.RestService;
import io.quarkus.test.scenarios.QuarkusScenario;
@@ -23,9 +31,23 @@
public class ReactiveRestClientIT {
private static final String HEMINGWAY_BOOKS = "In Our Time, The Sun Also Rises, A Farewell to Arms, The Old Man and the Sea";
+ private static WireMockServer mockServer;
+
+ static {
+ mockServer = new WireMockServer(WireMockConfiguration.options()
+ .dynamicPort()
+ .useChunkedTransferEncoding(NEVER));
+ mockServer.stubFor(WireMock.get(WireMock.urlPathMatching("/malformed/"))
+ .willReturn(WireMock.aResponse().withFault(Fault.MALFORMED_RESPONSE_CHUNK)));
+ mockServer.start();
+ }
+
+ static final String MALFORMED_URL = "quarkus.rest-client.\"io.quarkus.ts.http.restclient.reactive.MalformedClient\".url";
@QuarkusApplication
- static RestService app = new RestService().withProperties("modern.properties");
+ static RestService app = new RestService()
+ .withProperties("modern.properties")
+ .withProperty(MALFORMED_URL, () -> mockServer.baseUrl());
@Test
public void shouldGetBookFromRestClientJson() {
@@ -226,4 +248,15 @@ public void programmaticRestClient() {
.statusCode(200)
.body(is("The Hobbit: An Unexpected Journey"));
}
+
+ @Test
+ public void malformedChunk() {
+ Response response = app.given().get("/client/malformed");
+ Assertions.assertEquals("io.vertx.core.http.HttpClosedException", response.body().asString());
+ }
+
+ @AfterAll
+ static void afterAll() {
+ mockServer.stop();
+ }
}