From 48b963aaa5e122d8e21967c363233df245755d7e Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 10 Sep 2012 18:22:28 -0400 Subject: [PATCH] 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 --- .../ResponseEntityExceptionHandler.java | 4 ++++ .../support/DefaultHandlerExceptionResolver.java | 15 +++++++++++++-- .../ResponseEntityExceptionHandlerTests.java | 7 +++++++ .../DefaultHandlerExceptionResolverTests.java | 15 +++++++++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java index 598340c5e3..8e00031dc2 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java @@ -179,6 +179,10 @@ public abstract class ResponseEntityExceptionHandler { protected ResponseEntity 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(body, headers, status); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java index be2542d2b2..306b78a696 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java @@ -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. *

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(); } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java index e46c1872bb..c18059f0a9 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java @@ -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 testException(Exception ex) { ResponseEntity 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()); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolverTests.java index 9fdc1bdc7f..d29b1b6f81 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolverTests.java @@ -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) { }