Browse Source

Call getErrorAttributes() only once

Refine the fix introduced in commit 60b7e6cf23 so that the
`getErrorAttributes()` method is not called multiple times. If the
status is missing, the `DefaultErrorWebExceptionHandler` will now
call an internal `DefaultErrorAttributes` instance in order to obtain
the actual status result.

Fixes gh-41732
pull/42056/head
Phillip Webb 1 year ago
parent
commit
05b73ceeec
  1. 12
      spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandler.java
  2. 36
      spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandlerIntegrationTests.java

12
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandler.java

@ -30,6 +30,7 @@ import org.springframework.boot.autoconfigure.web.ErrorProperties; @@ -30,6 +30,7 @@ import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.WebProperties.Resources;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.error.ErrorAttributeOptions.Include;
import org.springframework.boot.web.reactive.error.DefaultErrorAttributes;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
@ -94,6 +95,8 @@ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHa @@ -94,6 +95,8 @@ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHa
private static final ErrorAttributeOptions ONLY_STATUS = ErrorAttributeOptions.of(Include.STATUS);
private static final DefaultErrorAttributes defaultErrorAttributes = new DefaultErrorAttributes();
private final ErrorProperties errorProperties;
/**
@ -121,8 +124,8 @@ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHa @@ -121,8 +124,8 @@ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHa
* @return a {@code Publisher} of the HTTP response
*/
protected Mono<ServerResponse> renderErrorView(ServerRequest request) {
int status = getHttpStatus(getErrorAttributes(request, ONLY_STATUS));
Map<String, Object> errorAttributes = getErrorAttributes(request, MediaType.TEXT_HTML);
int status = getHttpStatus(request, errorAttributes);
ServerResponse.BodyBuilder responseBody = ServerResponse.status(status).contentType(TEXT_HTML_UTF8);
return Flux.just(getData(status).toArray(new String[] {}))
.flatMap((viewName) -> renderErrorView(viewName, responseBody, errorAttributes))
@ -148,8 +151,8 @@ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHa @@ -148,8 +151,8 @@ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHa
* @return a {@code Publisher} of the HTTP response
*/
protected Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
int status = getHttpStatus(getErrorAttributes(request, ONLY_STATUS));
Map<String, Object> errorAttributes = getErrorAttributes(request, MediaType.ALL);
int status = getHttpStatus(request, errorAttributes);
return ServerResponse.status(status)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(errorAttributes));
@ -234,6 +237,11 @@ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHa @@ -234,6 +237,11 @@ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHa
};
}
private int getHttpStatus(ServerRequest request, Map<String, Object> errorAttributes) {
return getHttpStatus(errorAttributes.containsKey("status") ? errorAttributes
: defaultErrorAttributes.getErrorAttributes(request, ONLY_STATUS));
}
/**
* Get the HTTP error status information from the error map.
* @param errorAttributes the current error information

36
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandlerIntegrationTests.java

@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.web.reactive.error; @@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.web.reactive.error;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import jakarta.validation.Valid;
@ -597,6 +598,21 @@ class DefaultErrorWebExceptionHandlerIntegrationTests { @@ -597,6 +598,21 @@ class DefaultErrorWebExceptionHandlerIntegrationTests {
});
}
@Test
void customErrorAttributesWithoutStatus() {
this.contextRunner.withUserConfiguration(CustomErrorAttributesWithoutStatus.class).run((context) -> {
WebTestClient client = getWebClient(context);
client.get()
.uri("/badRequest")
.exchange()
.expectStatus()
.isBadRequest()
.expectBody()
.jsonPath("status")
.doesNotExist();
});
}
private String getErrorTemplatesLocation() {
String packageName = getClass().getPackage().getName();
return "classpath:/" + packageName.replace('.', '/') + "/templates/";
@ -686,6 +702,7 @@ class DefaultErrorWebExceptionHandlerIntegrationTests { @@ -686,6 +702,7 @@ class DefaultErrorWebExceptionHandlerIntegrationTests {
@Bean
ErrorAttributes errorAttributes() {
return new DefaultErrorAttributes() {
@Override
public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
Map<String, Object> errorAttributes = new HashMap<>();
@ -724,4 +741,23 @@ class DefaultErrorWebExceptionHandlerIntegrationTests { @@ -724,4 +741,23 @@ class DefaultErrorWebExceptionHandlerIntegrationTests {
}
@Configuration(proxyBeanMethods = false)
static class CustomErrorAttributesWithoutStatus {
@Bean
ErrorAttributes errorAttributes() {
return new DefaultErrorAttributes() {
@Override
public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
Map<String, Object> attributes = new LinkedHashMap<>(super.getErrorAttributes(request, options));
attributes.remove("status");
return attributes;
}
};
}
}
}

Loading…
Cancel
Save