I'm running Quarkus 2.7.0.CR1 with this code:
return httpRequest.sendBuffer(createBuffer())
.onSubscription()
.invoke(() -> metricsRecorder.start(METRICS_NAME))
.onFailure()
.recoverWithUni(failure -> fetchWithOtherCredentials())
...
onFailure()
triggers if port in URL is not responding at all. But when returning HTTP 500 from WireMock this code just throws WebApplicationException
with status 500 without triggering onFailure()
. This is the exception that triggers onFailure()
:
io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: localhost/127.0.0.1:8085
AnnotatedConnectException
seems to be checked exception but in this example IllegalArgumentException
is used which is RuntimeException
like WebApplicationException
.
I thought onFailure()
should trigger on any exception. Any ideas what is going on? I have tested with @QuarkusTest
and also by running Quarkus locally with mvn compile quarkus:dev
.
HttpRequest.sendBuffer()
returns a Uni<HttpResponse<T>>
. When the server responds with status 500
, the Web Client does not emit a failure, it emits an HttpResponse
with status code 500
.
You should inspect the response, like this:
Uni<HttpResponse> uni = httpRequest
.sendBuffer(createBuffer())
.onItem().transformToUni(res -> {
if (res.statusCode() == 200 && res.getHeader("content-type").equals("application/json")) {
// Do something with JSON body and return new Uni
} else {
// Generate failure as Uni
}
});
Another option is to use response predicates:
Uni<HttpResponse> uni = httpRequest
.expect(ResponsePredicate.SC_SUCCESS)
.expect(ResponsePredicate.JSON)
.sendBuffer(createBuffer());
In this case, the returned Uni<HttpResponse>
is successful only when the response has status code 200
and a JSON body, otherwise it is failed.