diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/reactive.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/reactive.adoc index 82292dbe64..6e5a2d1b60 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/reactive.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/reactive.adoc @@ -189,10 +189,8 @@ include::code:MyErrorWebExceptionHandler[] For a more complete picture, you can also subclass `DefaultErrorWebExceptionHandler` directly and override specific methods. -In some cases, errors handled at the controller or handler function level are not recorded by the <>. -Applications can ensure that such exceptions are recorded with the request metrics by setting the handled exception as a request attribute: - -include::code:MyExceptionHandlingController[] +In some cases, errors handled at the controller level are not recorded by web observations or the <>. +Applications can ensure that such exceptions are recorded with the observations by {spring-framework-docs}/integration/observability.html#observability.http-server.reactive[setting the handled exception on the observation context]. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/servlet.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/servlet.adoc index 19503eab07..fbc330fd0c 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/servlet.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/servlet.adoc @@ -355,10 +355,8 @@ include::code:MyControllerAdvice[] In the preceding example, if `MyException` is thrown by a controller defined in the same package as `SomeController`, a JSON representation of the `MyErrorBody` POJO is used instead of the `ErrorAttributes` representation. -In some cases, errors handled at the controller level are not recorded by the <>. -Applications can ensure that such exceptions are recorded with the request metrics by setting the handled exception as a request attribute: - -include::code:MyController[] +In some cases, errors handled at the controller level are not recorded by web observations or the <>. +Applications can ensure that such exceptions are recorded with the observations by {spring-framework-docs}/integration/observability.html#observability.http-server.servlet[setting the handled exception on the observation context]. diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/webflux/errorhandling/MyExceptionHandlingController.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/webflux/errorhandling/MyExceptionHandlingController.java deleted file mode 100644 index b1913940a8..0000000000 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/webflux/errorhandling/MyExceptionHandlingController.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2012-2021 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docs.web.reactive.webflux.errorhandling; - -import org.springframework.boot.web.reactive.error.ErrorAttributes; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.reactive.result.view.Rendering; -import org.springframework.web.server.ServerWebExchange; - -@Controller -public class MyExceptionHandlingController { - - @GetMapping("/profile") - public Rendering userProfile() { - // ... - throw new IllegalStateException(); - } - - @ExceptionHandler(IllegalStateException.class) - public Rendering handleIllegalState(ServerWebExchange exchange, IllegalStateException exc) { - exchange.getAttributes().putIfAbsent(ErrorAttributes.ERROR_ATTRIBUTE, exc); - return Rendering.view("errorView").modelAttribute("message", exc.getMessage()).build(); - } - -} diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/MyController.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/MyController.java deleted file mode 100644 index e93f0ba92b..0000000000 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/MyController.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2012-2021 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docs.web.servlet.springmvc.errorhandling; - -import jakarta.servlet.http.HttpServletRequest; - -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.ExceptionHandler; - -@Controller -public class MyController { - - @ExceptionHandler(CustomException.class) - String handleCustomException(HttpServletRequest request, CustomException ex) { - request.setAttribute(ErrorAttributes.ERROR_ATTRIBUTE, ex); - return "errorView"; - } - -} diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/webflux/errorhandling/MyExceptionHandlingController.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/webflux/errorhandling/MyExceptionHandlingController.kt deleted file mode 100644 index 26dfa251d4..0000000000 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/webflux/errorhandling/MyExceptionHandlingController.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2012-2022 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docs.web.reactive.webflux.errorhandling - -import org.springframework.boot.web.reactive.error.ErrorAttributes -import org.springframework.stereotype.Controller -import org.springframework.web.bind.annotation.ExceptionHandler -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.reactive.result.view.Rendering -import org.springframework.web.server.ServerWebExchange - -@Suppress("UNUSED_PARAMETER") -@Controller -class MyExceptionHandlingController { - - @GetMapping("/profile") - fun userProfile(): Rendering { - // ... - throw IllegalStateException() - } - - @ExceptionHandler(IllegalStateException::class) - fun handleIllegalState(exchange: ServerWebExchange, exc: IllegalStateException): Rendering { - exchange.attributes.putIfAbsent(ErrorAttributes.ERROR_ATTRIBUTE, exc) - return Rendering.view("errorView").modelAttribute("message", exc.message ?: "").build() - } - -} diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/MyController.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/MyController.kt deleted file mode 100644 index deead1e60d..0000000000 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/MyController.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2012-2022 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docs.web.servlet.springmvc.errorhandling - -import jakarta.servlet.http.HttpServletRequest -import org.springframework.boot.web.servlet.error.ErrorAttributes -import org.springframework.stereotype.Controller -import org.springframework.web.bind.annotation.ExceptionHandler - -@Controller -class MyController { - - @ExceptionHandler(CustomException::class) - fun handleCustomException(request: HttpServletRequest, ex: CustomException?): String { - request.setAttribute(ErrorAttributes.ERROR_ATTRIBUTE, ex) - return "errorView" - } - -} 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 d55366b53c..354b46988a 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 @@ -152,7 +152,6 @@ public class DefaultErrorAttributes implements ErrorAttributes { @Override public Throwable getError(ServerRequest request) { Optional error = request.attribute(ERROR_INTERNAL_ATTRIBUTE); - error.ifPresent((value) -> request.attributes().putIfAbsent(ErrorAttributes.ERROR_ATTRIBUTE, value)); return (Throwable) error .orElseThrow(() -> new IllegalStateException("Missing exception attribute in ServerWebExchange")); } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/ErrorAttributes.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/ErrorAttributes.java index 3c9a1d5567..aab94b4e31 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/ErrorAttributes.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/ErrorAttributes.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2023 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. @@ -34,13 +34,6 @@ import org.springframework.web.server.ServerWebExchange; */ public interface ErrorAttributes { - /** - * Name of the {@link ServerRequest#attribute(String) request attribute} holding the - * error resolved by the {@code ErrorAttributes} implementation. - * @since 2.5.0 - */ - String ERROR_ATTRIBUTE = ErrorAttributes.class.getName() + ".error"; - /** * Return a {@link Map} of the error attributes. The map can be used as the model of * an error page, or returned as a {@link ServerResponse} body. diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/DefaultErrorAttributes.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/DefaultErrorAttributes.java index 21e6bd068f..ef02be9670 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/DefaultErrorAttributes.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/DefaultErrorAttributes.java @@ -216,9 +216,6 @@ public class DefaultErrorAttributes implements ErrorAttributes, HandlerException if (exception == null) { exception = getAttribute(webRequest, RequestDispatcher.ERROR_EXCEPTION); } - // store the exception in a well-known attribute to make it available to metrics - // instrumentation. - webRequest.setAttribute(ErrorAttributes.ERROR_ATTRIBUTE, exception, WebRequest.SCOPE_REQUEST); return exception; } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/ErrorAttributes.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/ErrorAttributes.java index 898363885e..3f2fc64d1e 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/ErrorAttributes.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/ErrorAttributes.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2023 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. @@ -34,14 +34,6 @@ import org.springframework.web.servlet.ModelAndView; */ public interface ErrorAttributes { - /** - * Name of the {@link jakarta.servlet.http.HttpServletRequest#getAttribute(String) - * request attribute} holding the error resolved by the {@code ErrorAttributes} - * implementation. - * @since 2.5.0 - */ - String ERROR_ATTRIBUTE = ErrorAttributes.class.getName() + ".error"; - /** * Returns a {@link Map} of the error attributes. The map can be used as the model of * an error page {@link ModelAndView}, or returned as a 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 06633045c3..9b3d63375c 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 @@ -160,7 +160,6 @@ class DefaultErrorAttributesTests { Map attributes = this.errorAttributes.getErrorAttributes(serverRequest, ErrorAttributeOptions.of(Include.EXCEPTION, Include.MESSAGE)); assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error); - assertThat(serverRequest.attribute(ErrorAttributes.ERROR_ATTRIBUTE)).containsSame(error); assertThat(attributes).containsEntry("exception", RuntimeException.class.getName()); assertThat(attributes).containsEntry("message", "Test"); } @@ -178,7 +177,6 @@ class DefaultErrorAttributesTests { assertThat(attributes).containsEntry("message", "invalid request"); assertThat(attributes).containsEntry("exception", RuntimeException.class.getName()); assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error); - assertThat(serverRequest.attribute(ErrorAttributes.ERROR_ATTRIBUTE)).containsSame(error); } @Test @@ -194,7 +192,6 @@ class DefaultErrorAttributesTests { assertThat(attributes).containsEntry("message", "could not process request"); assertThat(attributes).containsEntry("exception", ResponseStatusException.class.getName()); assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error); - assertThat(serverRequest.attribute(ErrorAttributes.ERROR_ATTRIBUTE)).containsSame(error); } @Test diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/error/DefaultErrorAttributesTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/error/DefaultErrorAttributesTests.java index 71405232b6..fe6848d0cb 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/error/DefaultErrorAttributesTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/error/DefaultErrorAttributesTests.java @@ -88,8 +88,6 @@ class DefaultErrorAttributesTests { Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, ErrorAttributeOptions.of(Include.MESSAGE)); assertThat(this.errorAttributes.getError(this.webRequest)).isSameAs(ex); - assertThat(this.webRequest.getAttribute(ErrorAttributes.ERROR_ATTRIBUTE, WebRequest.SCOPE_REQUEST)) - .isSameAs(ex); assertThat(modelAndView).isNull(); assertThat(attributes).doesNotContainKey("exception"); assertThat(attributes).containsEntry("message", "Test"); @@ -102,8 +100,6 @@ class DefaultErrorAttributesTests { Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, ErrorAttributeOptions.of(Include.MESSAGE)); assertThat(this.errorAttributes.getError(this.webRequest)).isSameAs(ex); - assertThat(this.webRequest.getAttribute(ErrorAttributes.ERROR_ATTRIBUTE, WebRequest.SCOPE_REQUEST)) - .isSameAs(ex); assertThat(attributes).doesNotContainKey("exception"); assertThat(attributes).containsEntry("message", "Test"); } @@ -115,8 +111,6 @@ class DefaultErrorAttributesTests { Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, ErrorAttributeOptions.defaults()); assertThat(this.errorAttributes.getError(this.webRequest)).isSameAs(ex); - assertThat(this.webRequest.getAttribute(ErrorAttributes.ERROR_ATTRIBUTE, WebRequest.SCOPE_REQUEST)) - .isSameAs(ex); assertThat(attributes).doesNotContainKey("exception"); assertThat(attributes).doesNotContainKey("message"); } @@ -166,8 +160,6 @@ class DefaultErrorAttributesTests { Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, ErrorAttributeOptions.of(Include.MESSAGE)); assertThat(this.errorAttributes.getError(this.webRequest)).isSameAs(wrapped); - assertThat(this.webRequest.getAttribute(ErrorAttributes.ERROR_ATTRIBUTE, WebRequest.SCOPE_REQUEST)) - .isSameAs(wrapped); assertThat(attributes).doesNotContainKey("exception"); assertThat(attributes).containsEntry("message", "Test"); } @@ -179,8 +171,6 @@ class DefaultErrorAttributesTests { Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, ErrorAttributeOptions.of(Include.MESSAGE)); assertThat(this.errorAttributes.getError(this.webRequest)).isSameAs(error); - assertThat(this.webRequest.getAttribute(ErrorAttributes.ERROR_ATTRIBUTE, WebRequest.SCOPE_REQUEST)) - .isSameAs(error); assertThat(attributes).doesNotContainKey("exception"); assertThat(attributes).containsEntry("message", "Test error"); }