Skip to content

Commit a1463c2

Browse files
committed
Do not set exception attribute if response body is set
ResponseEntityExceptionHandler should not set the exception attribute when there is a response body, and the response is fully handled. Closes gh-31541
1 parent 23eff5c commit a1463c2

File tree

2 files changed

+14
-11
lines changed

2 files changed

+14
-11
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -560,14 +560,14 @@ protected ResponseEntity<Object> handleExceptionInternal(
560560
}
561561
}
562562

563-
if (statusCode.equals(HttpStatus.INTERNAL_SERVER_ERROR)) {
564-
request.setAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE, ex, WebRequest.SCOPE_REQUEST);
565-
}
566-
567563
if (body == null && ex instanceof ErrorResponse errorResponse) {
568564
body = errorResponse.updateAndGetBody(this.messageSource, LocaleContextHolder.getLocale());
569565
}
570566

567+
if (statusCode.equals(HttpStatus.INTERNAL_SERVER_ERROR) && body == null) {
568+
request.setAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE, ex, WebRequest.SCOPE_REQUEST);
569+
}
570+
571571
return createResponseEntity(body, headers, statusCode, request);
572572
}
573573

spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import org.springframework.core.MethodParameter;
3333
import org.springframework.http.HttpHeaders;
3434
import org.springframework.http.HttpMethod;
35-
import org.springframework.http.HttpStatus;
3635
import org.springframework.http.HttpStatusCode;
3736
import org.springframework.http.MediaType;
3837
import org.springframework.http.ProblemDetail;
@@ -267,6 +266,15 @@ public void asyncRequestTimeoutException() {
267266
testException(new AsyncRequestTimeoutException());
268267
}
269268

269+
@Test // gh-14287, gh-31541
270+
void serverErrorWithoutBody() {
271+
HttpStatusCode code = HttpStatusCode.valueOf(500);
272+
Exception ex = new IllegalStateException("internal error");
273+
this.exceptionHandler.handleExceptionInternal(ex, null, new HttpHeaders(), code, this.request);
274+
275+
assertThat(this.servletRequest.getAttribute("jakarta.servlet.error.exception")).isSameAs(ex);
276+
}
277+
270278
@Test
271279
public void controllerAdvice() throws Exception {
272280
StaticWebApplicationContext ctx = new StaticWebApplicationContext();
@@ -343,11 +351,6 @@ private ResponseEntity<Object> testException(Exception ex) {
343351
try {
344352
ResponseEntity<Object> entity = this.exceptionHandler.handleException(ex, this.request);
345353

346-
// SPR-9653
347-
if (HttpStatus.INTERNAL_SERVER_ERROR.equals(entity.getStatusCode())) {
348-
assertThat(this.servletRequest.getAttribute("jakarta.servlet.error.exception")).isSameAs(ex);
349-
}
350-
351354
// Verify DefaultHandlerExceptionResolver would set the same status
352355
this.exceptionResolver.resolveException(this.servletRequest, this.servletResponse, null, ex);
353356
assertThat(entity.getStatusCode().value()).isEqualTo(this.servletResponse.getStatus());

0 commit comments

Comments
 (0)