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
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -560,14 +560,14 @@ public abstract class ResponseEntityExceptionHandler implements MessageSourceAwa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statusCode.equals(HttpStatus.INTERNAL_SERVER_ERROR)) {
|
|
||||||
request.setAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE, ex, WebRequest.SCOPE_REQUEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (body == null && ex instanceof ErrorResponse errorResponse) {
|
if (body == null && ex instanceof ErrorResponse errorResponse) {
|
||||||
body = errorResponse.updateAndGetBody(this.messageSource, LocaleContextHolder.getLocale());
|
body = errorResponse.updateAndGetBody(this.messageSource, LocaleContextHolder.getLocale());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (statusCode.equals(HttpStatus.INTERNAL_SERVER_ERROR) && body == null) {
|
||||||
|
request.setAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE, ex, WebRequest.SCOPE_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
return createResponseEntity(body, headers, statusCode, request);
|
return createResponseEntity(body, headers, statusCode, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import org.springframework.context.support.StaticMessageSource;
|
|||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.HttpStatusCode;
|
import org.springframework.http.HttpStatusCode;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ProblemDetail;
|
import org.springframework.http.ProblemDetail;
|
||||||
@@ -267,6 +266,15 @@ public class ResponseEntityExceptionHandlerTests {
|
|||||||
testException(new AsyncRequestTimeoutException());
|
testException(new AsyncRequestTimeoutException());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // gh-14287, gh-31541
|
||||||
|
void serverErrorWithoutBody() {
|
||||||
|
HttpStatusCode code = HttpStatusCode.valueOf(500);
|
||||||
|
Exception ex = new IllegalStateException("internal error");
|
||||||
|
this.exceptionHandler.handleExceptionInternal(ex, null, new HttpHeaders(), code, this.request);
|
||||||
|
|
||||||
|
assertThat(this.servletRequest.getAttribute("jakarta.servlet.error.exception")).isSameAs(ex);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void controllerAdvice() throws Exception {
|
public void controllerAdvice() throws Exception {
|
||||||
StaticWebApplicationContext ctx = new StaticWebApplicationContext();
|
StaticWebApplicationContext ctx = new StaticWebApplicationContext();
|
||||||
@@ -343,11 +351,6 @@ public class ResponseEntityExceptionHandlerTests {
|
|||||||
try {
|
try {
|
||||||
ResponseEntity<Object> entity = this.exceptionHandler.handleException(ex, this.request);
|
ResponseEntity<Object> entity = this.exceptionHandler.handleException(ex, this.request);
|
||||||
|
|
||||||
// SPR-9653
|
|
||||||
if (HttpStatus.INTERNAL_SERVER_ERROR.equals(entity.getStatusCode())) {
|
|
||||||
assertThat(this.servletRequest.getAttribute("jakarta.servlet.error.exception")).isSameAs(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify DefaultHandlerExceptionResolver would set the same status
|
// Verify DefaultHandlerExceptionResolver would set the same status
|
||||||
this.exceptionResolver.resolveException(this.servletRequest, this.servletResponse, null, ex);
|
this.exceptionResolver.resolveException(this.servletRequest, this.servletResponse, null, ex);
|
||||||
assertThat(entity.getStatusCode().value()).isEqualTo(this.servletResponse.getStatus());
|
assertThat(entity.getStatusCode().value()).isEqualTo(this.servletResponse.getStatus());
|
||||||
|
|||||||
Reference in New Issue
Block a user