Made useGetCause and useHandledExceptionMessage bean properties
This commit is contained in:
@@ -18,18 +18,30 @@ public class AnnotationHandler implements HandlerExceptionResolver {
|
||||
protected static final String USER_TEMPLATE = "error.template";
|
||||
protected static final String DEFAULT_TEMPLATE = "defaults/default.template";
|
||||
private static final String UTF_8 = "UTF-8";
|
||||
private boolean useHandledExceptionMessage = true; //use the message from the annotated exception
|
||||
private boolean useGetCause = true;
|
||||
|
||||
public void setUseHandledExceptionMessage(boolean flag) {
|
||||
useHandledExceptionMessage = flag;
|
||||
}
|
||||
|
||||
public void setUseGetCause(boolean flag) {
|
||||
useGetCause = flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelAndView resolveException(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final Exception thrownException) {
|
||||
Exception rootException = getAnnotatedException(thrownException, thrownException.getCause());
|
||||
final ExceptionHandler annotation = getAnnotationFrom(rootException);
|
||||
final Exception handledException = getHandledException(thrownException);
|
||||
final ExceptionHandler annotation = getAnnotationFrom(handledException);
|
||||
final Exception messageException = getMessageException(thrownException, handledException);
|
||||
|
||||
try {
|
||||
if (annotation == null) {
|
||||
rootException.printStackTrace();
|
||||
return respondWithDefault(rootException, response);
|
||||
handledException.printStackTrace();
|
||||
return respondWithDefault(messageException, response);
|
||||
}
|
||||
return handleException(annotation, rootException, response);
|
||||
|
||||
return handleException(annotation, messageException, response);
|
||||
} catch (IOException e) {
|
||||
// potentially something went wrong in the response itself
|
||||
e.printStackTrace();
|
||||
@@ -38,31 +50,46 @@ public class AnnotationHandler implements HandlerExceptionResolver {
|
||||
return new ModelAndView();
|
||||
}
|
||||
|
||||
protected ModelAndView handleException(final ExceptionHandler annotation, final Exception thrownException, final HttpServletResponse response) throws IOException {
|
||||
protected Exception getHandledException(final Exception thrownException) {
|
||||
if(useGetCause) {
|
||||
return getAnnotatedException(thrownException, thrownException.getCause());
|
||||
}
|
||||
return thrownException;
|
||||
}
|
||||
|
||||
// This only matters if the user decides to use getCause
|
||||
protected Exception getMessageException(final Exception thrownException, final Exception annotatedException) {
|
||||
if(useHandledExceptionMessage) {
|
||||
return annotatedException;
|
||||
}
|
||||
return thrownException;
|
||||
}
|
||||
|
||||
protected ModelAndView handleException(final ExceptionHandler annotation, final Exception handledException, final HttpServletResponse response) throws IOException {
|
||||
response.setContentType(annotation.contentType());
|
||||
response.setStatus(annotation.httpStatus().value());
|
||||
|
||||
try {
|
||||
final String message = formatMessage(thrownException);
|
||||
final String message = formatMessage(handledException);
|
||||
response.getWriter().write(message);
|
||||
} catch (IOException e) {
|
||||
return respondWithDefault(thrownException, response);
|
||||
return respondWithDefault(handledException, response);
|
||||
}
|
||||
|
||||
return new ModelAndView();
|
||||
}
|
||||
|
||||
protected ModelAndView respondWithDefault(final Exception thrownException, final HttpServletResponse response) throws IOException {
|
||||
protected ModelAndView respondWithDefault(final Exception handledException, final HttpServletResponse response) throws IOException {
|
||||
response.setContentType(MediaType.APPLICATION_XML_VALUE);
|
||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||
response.getWriter().write(formatDefaultMessage(thrownException));
|
||||
response.getWriter().write(formatDefaultMessage(handledException));
|
||||
|
||||
return new ModelAndView();
|
||||
}
|
||||
|
||||
protected Exception getAnnotatedException(Exception thrownException, Throwable causedException) {
|
||||
if(getAnnotationFrom(thrownException) != null || causedException == null) {
|
||||
return thrownException;
|
||||
protected Exception getAnnotatedException(Exception exception, Throwable causedException) {
|
||||
if(getAnnotationFrom(exception) != null || causedException == null) {
|
||||
return exception;
|
||||
} else {
|
||||
return getAnnotatedException((Exception) causedException, causedException.getCause());
|
||||
}
|
||||
@@ -72,12 +99,12 @@ public class AnnotationHandler implements HandlerExceptionResolver {
|
||||
return exception.getClass().getAnnotation(ExceptionHandler.class);
|
||||
}
|
||||
|
||||
protected String formatMessage(final Exception thrownException) throws IOException {
|
||||
return String.format(readTemplate(), thrownException.getMessage());
|
||||
protected String formatMessage(final Exception handledException) throws IOException {
|
||||
return String.format(readTemplate(), handledException.getMessage());
|
||||
}
|
||||
|
||||
protected String formatDefaultMessage(final Exception thrownException) throws IOException {
|
||||
return String.format(readDefaultTemplate(), thrownException.getMessage());
|
||||
protected String formatDefaultMessage(final Exception handledException) throws IOException {
|
||||
return String.format(readDefaultTemplate(), handledException.getMessage());
|
||||
}
|
||||
|
||||
protected String readTemplate() throws IOException {
|
||||
|
||||
@@ -12,6 +12,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
@@ -239,7 +240,6 @@ public class AnnotationHandlerTest {
|
||||
|
||||
final AnnotationHandler sut = spy(new AnnotationHandler());
|
||||
doReturn(new ModelAndView()).when(sut).handleException(mockAnnotation, expectedException, mockResponse);
|
||||
doReturn(expectedException).when(sut).getAnnotatedException(expectedException, expectedException.getCause());
|
||||
doReturn(mockAnnotation).when(sut).getAnnotationFrom(expectedException);
|
||||
|
||||
final ModelAndView view = sut.resolveException(null, mockResponse, null, expectedException);
|
||||
@@ -247,6 +247,30 @@ public class AnnotationHandlerTest {
|
||||
verify(sut).handleException(mockAnnotation, expectedException, mockResponse);
|
||||
}
|
||||
|
||||
@Test public void getMessageException_ShouldReturnHandledException_WhenUseMessageExceptionIsTrue() throws Exception {
|
||||
final TestExceptionWithNoAnnotationAttributes expectedException = new TestExceptionWithNoAnnotationAttributes("");
|
||||
final TestExceptionWithNotFoundStatusCode thrownException = new TestExceptionWithNotFoundStatusCode();
|
||||
|
||||
final AnnotationHandler sut = spy(new AnnotationHandler());
|
||||
sut.setUseHandledExceptionMessage(true);
|
||||
|
||||
Exception messageException = sut.getMessageException(thrownException, expectedException);
|
||||
|
||||
assertEquals(expectedException, messageException);
|
||||
}
|
||||
|
||||
@Test public void getMessageException_ShouldReturnThrownException_WhenUseMessageExceptionIsFalse() throws Exception {
|
||||
final TestExceptionWithXmlContentType annotatedException = new TestExceptionWithXmlContentType();
|
||||
final TestExceptionWithNoAnnotation expectedException = new TestExceptionWithNoAnnotation("");
|
||||
|
||||
final AnnotationHandler sut = spy(new AnnotationHandler());
|
||||
sut.setUseHandledExceptionMessage(false);
|
||||
|
||||
Exception messageException = sut.getMessageException(expectedException, annotatedException);
|
||||
|
||||
assertEquals(expectedException, messageException);
|
||||
}
|
||||
|
||||
@Test public void resolveException_ShouldReturnDefaultErrorMessage_WhenUncheckedExceptionIsGiven() throws Exception {
|
||||
final NullPointerException expectedException = mock(NullPointerException.class);
|
||||
|
||||
@@ -263,7 +287,7 @@ public class AnnotationHandlerTest {
|
||||
verify(sut).respondWithDefault(expectedException, mockResponse);
|
||||
}
|
||||
|
||||
@Test public void getAnnotatedException_ShouldReturnOutermostAnnotatedException_WhenThereAreCheckedExceptionsChained() throws Exception {
|
||||
@Test public void getAnnotatedException_ShouldReturnOutermostAnnotatedException_WhenThereAreCheckedExceptionsChainedAndGetCauseIsTrue() throws Exception {
|
||||
TestExceptionWithNoAnnotationAttributes mockException = mock(TestExceptionWithNoAnnotationAttributes.class);
|
||||
doReturn(new TestExceptionWithXmlContentType()).when(mockException).getCause();
|
||||
|
||||
@@ -279,7 +303,23 @@ public class AnnotationHandlerTest {
|
||||
Assert.assertTrue(sut.getAnnotatedException(mockException,mockException.getCause()) instanceof TestExceptionWithNoAnnotationAttributes);
|
||||
}
|
||||
|
||||
@Test public void getAnnotatedException_ShouldReturnFirstChainedAnnotatedException_WhenThrownExceptionIsUnannotated() throws Exception {
|
||||
@Test public void getHandledException_ShouldReturnThrownException_WhenThereAreCheckedExceptionsChainedAndGetCauseIsFalse() throws Exception {
|
||||
TestExceptionWithNoAnnotationAttributes mockException = mock(TestExceptionWithNoAnnotationAttributes.class);
|
||||
doReturn(new TestExceptionWithXmlContentType()).when(mockException).getCause();
|
||||
|
||||
final ExceptionHandler mockAnnotation = mock(ExceptionHandler.class);
|
||||
final HttpServletResponse mockResponse = mock(HttpServletResponse.class);
|
||||
|
||||
final AnnotationHandler sut = spy(new AnnotationHandler());
|
||||
when(sut.getAnnotationFrom(mockException)).thenReturn(mockAnnotation);
|
||||
doReturn(new ModelAndView()).when(sut).handleException(mockAnnotation, mockException, mockResponse);
|
||||
|
||||
final ModelAndView view = sut.resolveException(null, mockResponse, null, mockException);
|
||||
|
||||
Assert.assertTrue(sut.getAnnotatedException(mockException,mockException.getCause()) instanceof TestExceptionWithNoAnnotationAttributes);
|
||||
}
|
||||
|
||||
@Test public void getHandledException_ShouldReturnFirstChainedAnnotatedException_WhenThrownExceptionIsUnannotatedAndGetCauseIsTrue() throws Exception {
|
||||
TestExceptionWithNoAnnotation mockException = mock(TestExceptionWithNoAnnotation.class);
|
||||
TestExceptionWithNoAnnotationAttributes expectedException = new TestExceptionWithNoAnnotationAttributes("");
|
||||
doReturn(expectedException).when(mockException).getCause();
|
||||
@@ -291,9 +331,17 @@ public class AnnotationHandlerTest {
|
||||
when(sut.getAnnotationFrom(expectedException)).thenReturn(mockAnnotation);
|
||||
doReturn(new ModelAndView()).when(sut).handleException(mockAnnotation, expectedException, mockResponse);
|
||||
|
||||
final ModelAndView view = sut.resolveException(null, mockResponse, null, expectedException);
|
||||
Assert.assertTrue(sut.getHandledException(mockException) instanceof TestExceptionWithNoAnnotationAttributes);
|
||||
}
|
||||
|
||||
Assert.assertTrue(sut.getAnnotatedException(mockException,mockException.getCause()) instanceof TestExceptionWithNoAnnotationAttributes);
|
||||
@Test public void getHandledException_ShouldReturnThrownException_WhenThrownExceptionIsUnannotatedAndGetCauseIsFalse() throws Exception {
|
||||
TestExceptionWithNoAnnotation expectedException = new TestExceptionWithNoAnnotation("");
|
||||
|
||||
final AnnotationHandler sut = new AnnotationHandler();
|
||||
sut.setUseGetCause(false);
|
||||
Exception actualException = sut.getHandledException(expectedException);
|
||||
|
||||
Assert.assertTrue(actualException instanceof TestExceptionWithNoAnnotation);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user