Add error request attribute for 500 reponses

DefaultHandlerExceptionResolver and ResponseEntityExceptionHandler now
both set the "javax.servlet.error.exception" request attribute to the
raised exception, allowing custom error pages configured via web.xml.

Issue: SPR-9653
This commit is contained in:
Rossen Stoyanchev
2012-09-10 18:22:28 -04:00
parent 787d8f5916
commit 48b963aaa5
4 changed files with 39 additions and 2 deletions

View File

@@ -179,6 +179,10 @@ public abstract class ResponseEntityExceptionHandler {
protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body,
HttpHeaders headers, HttpStatus status, WebRequest request) {
if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) {
request.setAttribute("javax.servlet.error.exception", ex, WebRequest.SCOPE_REQUEST);
}
return new ResponseEntity<Object>(body, headers, status);
}

View File

@@ -294,10 +294,21 @@ public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionRes
protected ModelAndView handleConversionNotSupported(ConversionNotSupportedException ex,
HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
sendServerError(ex, request, response);
return new ModelAndView();
}
/**
* Invoked to send a server error. Sets the status to 500 and also sets the
* request attribute "javax.servlet.error.exception" to the Exception.
*/
protected void sendServerError(Exception ex,
HttpServletRequest request, HttpServletResponse response) throws IOException {
request.setAttribute("javax.servlet.error.exception", ex);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
/**
* Handle the case when a {@link org.springframework.web.bind.WebDataBinder} conversion error occurs.
* <p>The default implementation sends an HTTP 400 error, and returns an empty {@code ModelAndView}.
@@ -352,7 +363,7 @@ public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionRes
protected ModelAndView handleHttpMessageNotWritable(HttpMessageNotWritableException ex,
HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
sendServerError(ex, request, response);
return new ModelAndView();
}

View File

@@ -16,6 +16,7 @@
package org.springframework.web.servlet.mvc.method.annotation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.Method;
@@ -204,6 +205,12 @@ public class ResponseEntityExceptionHandlerTests {
private ResponseEntity<Object> testException(Exception ex) {
ResponseEntity<Object> responseEntity = this.exceptionHandlerSupport.handleException(ex, this.request);
// SPR-9653
if (HttpStatus.INTERNAL_SERVER_ERROR.equals(responseEntity.getStatusCode())) {
assertSame(ex, this.servletRequest.getAttribute("javax.servlet.error.exception"));
}
this.defaultExceptionResolver.resolveException(this.servletRequest, this.servletResponse, null, ex);
assertEquals(this.servletResponse.getStatus(), responseEntity.getStatusCode().value());

View File

@@ -18,12 +18,14 @@ package org.springframework.web.servlet.mvc.support;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.util.Collections;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TestBean;
import org.springframework.beans.TypeMismatchException;
import org.springframework.core.MethodParameter;
@@ -169,6 +171,19 @@ public class DefaultHandlerExceptionResolverTests {
assertEquals("Invalid status code", 400, response.getStatus());
}
@Test
public void handleConversionNotSupportedException() throws Exception {
ConversionNotSupportedException ex =
new ConversionNotSupportedException(new Object(), String.class, new Exception());
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
assertNotNull("No ModelAndView returned", mav);
assertTrue("No Empty ModelAndView returned", mav.isEmpty());
assertEquals("Invalid status code", 500, response.getStatus());
// SPR-9653
assertSame(ex, request.getAttribute("javax.servlet.error.exception"));
}
public void handle(String arg) {
}