import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.reactive.function.client.WebClientResponseException;
+import org.springframework.web.reactive.function.client.WebClientResponseException.NotFound;
import reactor.core.publisher.Mono;
@GetMapping(path = { "", "/" }, produces = MediaType.TEXT_PLAIN_VALUE)
public Mono<String> fetch(@RequestParam String path)
{
- return service.getRemoteText(path);
+ return
+ service
+ .getRemoteText(path)
+ .onErrorResume(t ->
+ {
+ if(t.getClass().equals(NotFound.class))
+ return Mono.error(t);
+
+ return
+ Mono.error(
+ WebClientResponseException.create(
+ 503,
+ "Service Unavailable - Cause: " + t.getMessage(),
+ null,
+ null,
+ null));
+ });
}
}
package de.juplo.demo;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
import org.mockito.Mockito;
import static org.mockito.Mockito.when;
+import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.client.WebClientResponseException;
import org.springframework.web.reactive.function.client.WebClientResponseException.NotFound;
+import org.springframework.web.reactive.function.client.WebClientResponseException.ServiceUnavailable;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
.verify();
}
+ /**
+ * Only the behavior on the common errors, as defined in {@link
+ * WebClientResponseException#create(int, String, org.springframework.http.HttpHeaders, byte[], java.nio.charset.Charset, org.springframework.http.HttpRequest)
+ * WebClientResponseException.create()} is tested.
+ */
+ @DisplayName("Other error while fetching data from remote-server")
+ @ParameterizedTest(name = "{arguments} ==> HTTP-status={0}")
+ @EnumSource(value = HttpStatus.class, names = {
+ "BAD_REQUEST",
+ "UNAUTHORIZED",
+ "FORBIDDEN",
+ "METHOD_NOT_ALLOWED",
+ "NOT_ACCEPTABLE",
+ "CONFLICT",
+ "GONE",
+ "UNSUPPORTED_MEDIA_TYPE",
+ "TOO_MANY_REQUESTS",
+ "UNPROCESSABLE_ENTITY",
+ "INTERNAL_SERVER_ERROR",
+ "NOT_IMPLEMENTED",
+ "BAD_GATEWAY",
+ "SERVICE_UNAVAILABLE",
+ "GATEWAY_TIMEOUT"
+ })
+ void testResponseOtherErrors(HttpStatus status)
+ {
+ Mono<String> mono = Mono.error(exception(status.value()));
+ when(service.getRemoteText("foo")).thenReturn(mono);
+
+ Mono<String> result = controller.fetch("foo");
+
+ StepVerifier
+ .create(result)
+ .expectErrorSatisfies((t) ->
+ {
+ assertThat(t).isInstanceOf(ServiceUnavailable.class);
+ assertThat(t.getMessage())
+ .startsWith(
+ "503 Service Unavailable - Cause: " +
+ Integer.toString(status.value()));
+ })
+ .verify();
+ }
+
WebClientResponseException exception(int status)
{