From 17919749db312de7f3fb3de80114b6f7a512637a Mon Sep 17 00:00:00 2001 From: Michele Mancioppi Date: Tue, 9 Oct 2018 20:48:20 +0200 Subject: [PATCH 1/2] Add support for @ResponseStatus in DefaultErrorAttributes This commit adds support for @ResponseStatus in DefaultErrorAttributes mimicking the semantics of @ResponseStatus in SpringMVC. Throwables annotated with @ResponseStatus handled by DefaultErrorAttributes will result in the following error attributes: * 'status' set as the return value of the HttpStatus#value() defined as @ResponseStatus#value() * 'error' set to the default reason phrase of the HttpStatus defined as @ResponseStatus#value() * 'message' defined as the value of @ResponseStatus#reason(), or the default HttpStatus's reason phrase if left unspecified See gh-14744 --- .../error/DefaultErrorAttributes.java | 20 +++++++++++ .../error/DefaultErrorAttributesTests.java | 34 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java index 577586d06e..48d3dd2724 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java @@ -22,9 +22,11 @@ import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; +import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.http.HttpStatus; import org.springframework.validation.BindingResult; import org.springframework.validation.ObjectError; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.support.WebExchangeBindException; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.server.ResponseStatusException; @@ -46,6 +48,7 @@ import org.springframework.web.server.ServerWebExchange; * * @author Brian Clozel * @author Stephane Nicoll + * @author Michele Mancioppi * @since 2.0.0 * @see ErrorAttributes */ @@ -91,6 +94,14 @@ public class DefaultErrorAttributes implements ErrorAttributes { if (error instanceof ResponseStatusException) { return ((ResponseStatusException) error).getStatus(); } + + ResponseStatus responseStatus = AnnotatedElementUtils + .findMergedAnnotation(error.getClass(), ResponseStatus.class); + + if (responseStatus != null) { + return responseStatus.code(); + } + return HttpStatus.INTERNAL_SERVER_ERROR; } @@ -98,9 +109,18 @@ public class DefaultErrorAttributes implements ErrorAttributes { if (error instanceof WebExchangeBindException) { return error.getMessage(); } + if (error instanceof ResponseStatusException) { return ((ResponseStatusException) error).getReason(); } + + ResponseStatus responseStatus = AnnotatedElementUtils + .findMergedAnnotation(error.getClass(), ResponseStatus.class); + + if (responseStatus != null) { + return responseStatus.reason(); + } + return error.getMessage(); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributesTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributesTests.java index 1a676c16d3..a22151d152 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributesTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributesTests.java @@ -35,6 +35,7 @@ import org.springframework.mock.web.server.MockServerWebExchange; import org.springframework.validation.BindingResult; import org.springframework.validation.MapBindingResult; import org.springframework.validation.ObjectError; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.support.WebExchangeBindException; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.server.ResponseStatusException; @@ -90,6 +91,29 @@ public class DefaultErrorAttributesTests { assertThat(attributes.get("status")).isEqualTo(500); } + @Test + public void annotatedResponseStatusCode() { + Exception error = new CustomException(); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes + .getErrorAttributes(buildServerRequest(request, error), false); + assertThat(attributes.get("error")) + .isEqualTo(HttpStatus.I_AM_A_TEAPOT.getReasonPhrase()); + assertThat(attributes.get("status")).isEqualTo(HttpStatus.I_AM_A_TEAPOT.value()); + } + + @Test + public void annotatedResponseStatusCodeWithCustomReasonPhrase() { + Exception error = new Custom2Exception(); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes + .getErrorAttributes(buildServerRequest(request, error), false); + assertThat(attributes.get("error")) + .isEqualTo(HttpStatus.I_AM_A_TEAPOT.getReasonPhrase()); + assertThat(attributes.get("status")).isEqualTo(HttpStatus.I_AM_A_TEAPOT.value()); + assertThat(attributes.get("message")).isEqualTo("Nope!"); + } + @Test public void includeStatusCode() { MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); @@ -214,4 +238,14 @@ public class DefaultErrorAttributesTests { return 42; } + @ResponseStatus(HttpStatus.I_AM_A_TEAPOT) + private static class CustomException extends RuntimeException { + + } + + @ResponseStatus(value = HttpStatus.I_AM_A_TEAPOT, reason = "Nope!") + private static class Custom2Exception extends RuntimeException { + + } + } From 798b37805d6f41abb6a61f995891cc61637fd904 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 12 Oct 2018 15:57:57 +0200 Subject: [PATCH 2/2] Polish "Add support for @ResponseStatus in DefaultErrorAttributes" Closes gh-14744 --- .../boot/web/reactive/error/DefaultErrorAttributes.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java index 48d3dd2724..3054d2d18c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java @@ -94,14 +94,11 @@ public class DefaultErrorAttributes implements ErrorAttributes { if (error instanceof ResponseStatusException) { return ((ResponseStatusException) error).getStatus(); } - ResponseStatus responseStatus = AnnotatedElementUtils .findMergedAnnotation(error.getClass(), ResponseStatus.class); - if (responseStatus != null) { return responseStatus.code(); } - return HttpStatus.INTERNAL_SERVER_ERROR; } @@ -109,18 +106,14 @@ public class DefaultErrorAttributes implements ErrorAttributes { if (error instanceof WebExchangeBindException) { return error.getMessage(); } - if (error instanceof ResponseStatusException) { return ((ResponseStatusException) error).getReason(); } - ResponseStatus responseStatus = AnnotatedElementUtils .findMergedAnnotation(error.getClass(), ResponseStatus.class); - if (responseStatus != null) { return responseStatus.reason(); } - return error.getMessage(); }