Consistent handling of 4xx/5xx status codes in WebClient
This commit changes the handling of 4xx/5xx status codes in the WebClient to the following simple rule: if there is no way for the user to get the response status code, then a WebClientException is returned. If there is a way to get to the status code, then we do not return an exception. Issue: SPR-15486
This commit is contained in:
@@ -29,7 +29,6 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.codec.StringDecoder;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
@@ -48,7 +47,7 @@ import org.springframework.util.MultiValueMap;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.*;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.toMono;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
@@ -151,24 +150,6 @@ public class DefaultClientResponseTests {
|
||||
assertEquals("foo", resultMono.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bodyToMonoError() throws Exception {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.setContentType(MediaType.TEXT_PLAIN);
|
||||
when(mockResponse.getHeaders()).thenReturn(httpHeaders);
|
||||
when(mockResponse.getStatusCode()).thenReturn(HttpStatus.NOT_FOUND);
|
||||
|
||||
Set<HttpMessageReader<?>> messageReaders = Collections
|
||||
.singleton(new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes(true)));
|
||||
when(mockExchangeStrategies.messageReaders()).thenReturn(messageReaders::stream);
|
||||
|
||||
Mono<String> resultMono = defaultClientResponse.bodyToMono(String.class);
|
||||
|
||||
StepVerifier.create(resultMono)
|
||||
.expectError(WebClientException.class)
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bodyToFlux() throws Exception {
|
||||
DefaultDataBufferFactory factory = new DefaultDataBufferFactory();
|
||||
@@ -191,21 +172,4 @@ public class DefaultClientResponseTests {
|
||||
assertEquals(Collections.singletonList("foo"), result.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bodyToFluxError() throws Exception {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.setContentType(MediaType.TEXT_PLAIN);
|
||||
when(mockResponse.getHeaders()).thenReturn(httpHeaders);
|
||||
when(mockResponse.getStatusCode()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
|
||||
Set<HttpMessageReader<?>> messageReaders = Collections
|
||||
.singleton(new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes(true)));
|
||||
when(mockExchangeStrategies.messageReaders()).thenReturn(messageReaders::stream);
|
||||
|
||||
Flux<String> resultFlux = defaultClientResponse.bodyToFlux(String.class);
|
||||
StepVerifier.create(resultFlux)
|
||||
.expectError(WebClientException.class)
|
||||
.verify();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ public class WebClientIntegrationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notFound() throws Exception {
|
||||
public void exchangeNotFound() throws Exception {
|
||||
this.server.enqueue(new MockResponse().setResponseCode(404)
|
||||
.setHeader("Content-Type", "text/plain").setBody("Not Found"));
|
||||
|
||||
@@ -351,6 +351,47 @@ public class WebClientIntegrationTests {
|
||||
Assert.assertEquals("/greeting?name=Spring", recordedRequest.getPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retrieveBodyToMonoNotFound() throws Exception {
|
||||
this.server.enqueue(new MockResponse().setResponseCode(404)
|
||||
.setHeader("Content-Type", "text/plain").setBody("Not Found"));
|
||||
|
||||
Mono<String> result = this.webClient.get()
|
||||
.uri("/greeting?name=Spring")
|
||||
.retrieve()
|
||||
.bodyToMono(String.class);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectError(WebClientException.class)
|
||||
.verify(Duration.ofSeconds(3));
|
||||
|
||||
RecordedRequest recordedRequest = server.takeRequest();
|
||||
Assert.assertEquals(1, server.getRequestCount());
|
||||
Assert.assertEquals("*/*", recordedRequest.getHeader(HttpHeaders.ACCEPT));
|
||||
Assert.assertEquals("/greeting?name=Spring", recordedRequest.getPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retrieveToEntityNotFound() throws Exception {
|
||||
this.server.enqueue(new MockResponse().setResponseCode(404)
|
||||
.setHeader("Content-Type", "text/plain").setBody("Not Found"));
|
||||
|
||||
Mono<ResponseEntity<String>> result = this.webClient.get()
|
||||
.uri("/greeting?name=Spring")
|
||||
.retrieve()
|
||||
.toEntity(String.class);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.consumeNextWith(response -> assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode()))
|
||||
.expectComplete()
|
||||
.verify(Duration.ofSeconds(3));
|
||||
|
||||
RecordedRequest recordedRequest = server.takeRequest();
|
||||
Assert.assertEquals(1, server.getRequestCount());
|
||||
Assert.assertEquals("*/*", recordedRequest.getHeader(HttpHeaders.ACCEPT));
|
||||
Assert.assertEquals("/greeting?name=Spring", recordedRequest.getPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildFilter() throws Exception {
|
||||
this.server.enqueue(new MockResponse().setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
|
||||
|
||||
Reference in New Issue
Block a user