Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add status handler to recognize unknown status codes outside of 4xx/5… #31202

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ default boolean isSameCodeAs(HttpStatusCode other) {
return value() == other.value();
}

/**
* Checks whether this status code is a well-known HTTP status code or not
* @return {@code true} if the status code corresponds to a standard HTTP status code, {@code false} otherwise
*/
default boolean isWellKnown() {
return HttpStatus.resolve(this.value()) != null;
}
duesenklipper marked this conversation as resolved.
Show resolved Hide resolved

/**
* Return an {@code HttpStatusCode} object for the given integer value.
* @param code the status code as integer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -516,9 +516,11 @@ private void initCookies(MultiValueMap<String, String> out) {
private static class DefaultResponseSpec implements ResponseSpec {

private static final Predicate<HttpStatusCode> STATUS_CODE_ERROR = HttpStatusCode::isError;

private static final StatusHandler DEFAULT_STATUS_HANDLER =
private static final Predicate<HttpStatusCode> STATUS_CODE_UNKNOWN = status -> !status.isWellKnown();
private static final StatusHandler DEFAULT_ERROR_STATUS_HANDLER =
new StatusHandler(STATUS_CODE_ERROR, ClientResponse::createException);
private static final StatusHandler DEFAULT_UNKNOWN_STATUS_HANDLER =
new StatusHandler(STATUS_CODE_UNKNOWN, ClientResponse::createException);

private final HttpMethod httpMethod;

Expand All @@ -537,7 +539,8 @@ private static class DefaultResponseSpec implements ResponseSpec {
this.uri = uri;
this.responseMono = responseMono;
this.statusHandlers.addAll(defaultStatusHandlers);
this.statusHandlers.add(DEFAULT_STATUS_HANDLER);
this.statusHandlers.add(DEFAULT_ERROR_STATUS_HANDLER);
this.statusHandlers.add(DEFAULT_UNKNOWN_STATUS_HANDLER);
this.defaultStatusHandlerCount = this.statusHandlers.size();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,40 @@ void retrieve555UnknownStatus(ClientHttpConnector connector) {
});
}

@ParameterizedWebClientTest
void retrieve929CustomUnknownStatus(ClientHttpConnector connector) {
startServer(connector);

int errorStatus = 929;
assertThat(HttpStatus.resolve(errorStatus)).isNull();
String errorMessage = "Something went wrong";
prepareResponse(response -> response.setResponseCode(errorStatus)
.setHeader("Content-Type", "text/plain").setBody(errorMessage));

Mono<String> result = this.webClient.get()
.uri("/unknownPage")
.retrieve()
.bodyToMono(String.class);

StepVerifier.create(result)
.expectErrorSatisfies(throwable -> {
assertThat(throwable).isInstanceOf(UnknownHttpStatusCodeException.class);
UnknownHttpStatusCodeException ex = (UnknownHttpStatusCodeException) throwable;
assertThat(ex.getMessage()).isEqualTo(("Unknown status code ["+errorStatus+"]"));
assertThat(ex.getStatusCode().value()).isEqualTo(errorStatus);
assertThat(ex.getStatusText()).isEmpty();
assertThat(ex.getHeaders().getContentType()).isEqualTo(MediaType.TEXT_PLAIN);
assertThat(ex.getResponseBodyAsString()).isEqualTo(errorMessage);
})
.verify(Duration.ofSeconds(3));

expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo("*/*");
assertThat(request.getPath()).isEqualTo("/unknownPage");
});
}

@ParameterizedWebClientTest
void postPojoAsJson(ClientHttpConnector connector) {
startServer(connector);
Expand Down