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 df57aeef2d..b591aea755 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import org.springframework.core.annotation.MergedAnnotation; import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; import org.springframework.http.HttpStatus; +import org.springframework.util.StringUtils; import org.springframework.validation.BindingResult; import org.springframework.validation.ObjectError; import org.springframework.web.bind.annotation.ResponseStatus; @@ -108,7 +109,11 @@ public class DefaultErrorAttributes implements ErrorAttributes { if (error instanceof ResponseStatusException) { return ((ResponseStatusException) error).getReason(); } - return responseStatusAnnotation.getValue("reason", String.class).orElseGet(error::getMessage); + String reason = responseStatusAnnotation.getValue("reason", String.class).orElse(""); + if (StringUtils.hasText(reason)) { + return reason; + } + return (error.getMessage() != null) ? error.getMessage() : ""; } private Throwable determineException(Throwable error) { 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 930024ad80..1d6227c7ba 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -89,6 +89,18 @@ class DefaultErrorAttributesTests { Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, error), false); assertThat(attributes.get("error")).isEqualTo(HttpStatus.I_AM_A_TEAPOT.getReasonPhrase()); + assertThat(attributes.get("message")).isEqualTo(""); + assertThat(attributes.get("status")).isEqualTo(HttpStatus.I_AM_A_TEAPOT.value()); + } + + @Test + void annotatedResponseStatusCodeWithExceptionMessage() { + Exception error = new CustomException("Test Message"); + 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("message")).isEqualTo("Test Message"); assertThat(attributes.get("status")).isEqualTo(HttpStatus.I_AM_A_TEAPOT.value()); } @@ -226,6 +238,13 @@ class DefaultErrorAttributesTests { @ResponseStatus(HttpStatus.I_AM_A_TEAPOT) static class CustomException extends RuntimeException { + CustomException() { + } + + CustomException(String message) { + super(message); + } + } @ResponseStatus(value = HttpStatus.I_AM_A_TEAPOT, reason = "Nope!")