Modified the annotationHandler to use getCause but it always finds the innermost annotation
This commit is contained in:
@@ -19,24 +19,24 @@ public class AnnotationHandler implements HandlerExceptionResolver {
|
|||||||
protected static final String DEFAULT_TEMPLATE = "defaults/default.template";
|
protected static final String DEFAULT_TEMPLATE = "defaults/default.template";
|
||||||
private static final String UTF_8 = "UTF-8";
|
private static final String UTF_8 = "UTF-8";
|
||||||
|
|
||||||
//TODO: When there's a wrapper exception leave it unannotated… call the e.getCause() method… until there is an annotated exception or if there are no more causes (e.geCause()==null)??.
|
//TODO: When there's a wrapper exception leave it unannotated… call the e.getCause() method… until there is an annotated exception or if there are no more causes (e.geCause()==null)??
|
||||||
/* If the exception thrown is annotated, use the message from that
|
/* [ ] If the exception thrown is annotated, use the message from that
|
||||||
* If it is not annotated, call getCause() until you reach the innermost annotated exception. Use that message.
|
* [x] If it is not annotated, call getCause() until you reach the innermost annotated exception. Use that message.
|
||||||
* If getCause()==null, return the default message and response code
|
* [ ] If getCause()==null, return the default message and response code
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ModelAndView resolveException(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final Exception thrownException) {
|
public ModelAndView resolveException(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final Exception thrownException) {
|
||||||
final ExceptionHandler annotation = getAnnotationFrom(thrownException);
|
Exception rootException = getRootException(thrownException, thrownException.getCause());
|
||||||
|
final ExceptionHandler annotation = getAnnotationFrom(rootException);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (annotation == null) {
|
if (annotation == null) {
|
||||||
thrownException.printStackTrace();
|
rootException.printStackTrace();
|
||||||
return respondWithDefault(thrownException, response);
|
return respondWithDefault(rootException, response);
|
||||||
}
|
}
|
||||||
|
return handleException(annotation, rootException, response);
|
||||||
return handleException(annotation, thrownException, response);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// potentially something went wrong in response itself
|
// potentially something went wrong in the response itself
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,8 +65,16 @@ public class AnnotationHandler implements HandlerExceptionResolver {
|
|||||||
return new ModelAndView();
|
return new ModelAndView();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ExceptionHandler getAnnotationFrom(Exception thrownException) {
|
protected Exception getRootException(Exception thrownException, Throwable causedException) {
|
||||||
return thrownException.getClass().getAnnotation(ExceptionHandler.class);
|
if(causedException == null || getAnnotationFrom((Exception)causedException)==null) {
|
||||||
|
return thrownException;
|
||||||
|
} else {
|
||||||
|
return getRootException((Exception) causedException, causedException.getCause());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ExceptionHandler getAnnotationFrom(Exception exception) {
|
||||||
|
return exception.getClass().getAnnotation(ExceptionHandler.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String formatMessage(final Exception thrownException) throws IOException {
|
protected String formatMessage(final Exception thrownException) throws IOException {
|
||||||
|
|||||||
@@ -13,7 +13,12 @@ import java.io.InputStream;
|
|||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
import static org.mockito.Matchers.anyString;
|
import static org.mockito.Matchers.anyString;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.doThrow;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
public class AnnotationHandlerTest {
|
public class AnnotationHandlerTest {
|
||||||
|
|
||||||
@@ -234,6 +239,7 @@ public class AnnotationHandlerTest {
|
|||||||
|
|
||||||
final AnnotationHandler sut = spy(new AnnotationHandler());
|
final AnnotationHandler sut = spy(new AnnotationHandler());
|
||||||
doReturn(new ModelAndView()).when(sut).handleException(mockAnnotation, expectedException, mockResponse);
|
doReturn(new ModelAndView()).when(sut).handleException(mockAnnotation, expectedException, mockResponse);
|
||||||
|
doReturn(expectedException).when(sut).getRootException(expectedException, expectedException.getCause());
|
||||||
doReturn(mockAnnotation).when(sut).getAnnotationFrom(expectedException);
|
doReturn(mockAnnotation).when(sut).getAnnotationFrom(expectedException);
|
||||||
|
|
||||||
final ModelAndView view = sut.resolveException(null, mockResponse, null, expectedException);
|
final ModelAndView view = sut.resolveException(null, mockResponse, null, expectedException);
|
||||||
@@ -249,12 +255,36 @@ public class AnnotationHandlerTest {
|
|||||||
when(mockResponse.getWriter()).thenReturn(mockPrinter);
|
when(mockResponse.getWriter()).thenReturn(mockPrinter);
|
||||||
|
|
||||||
final AnnotationHandler sut = spy(new AnnotationHandler());
|
final AnnotationHandler sut = spy(new AnnotationHandler());
|
||||||
doReturn(null).when(sut).getAnnotationFrom(expectedException);
|
when(sut.getRootException(expectedException, expectedException.getCause())).thenReturn(expectedException);
|
||||||
|
when(sut.getAnnotationFrom(expectedException)).thenReturn(null);
|
||||||
|
|
||||||
final ModelAndView view = sut.resolveException(null, mockResponse, null, expectedException);
|
final ModelAndView view = sut.resolveException(null, mockResponse, null, expectedException);
|
||||||
|
|
||||||
verify(sut).respondWithDefault(expectedException, mockResponse);
|
verify(sut).respondWithDefault(expectedException, mockResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Mock the getCause() method to return TestExceptionWithNoAnnotation
|
||||||
|
// Instead of the actual exception, use the getCause() mocked one
|
||||||
|
// To pass into the annotationHandler method
|
||||||
|
// Check that the response is the correct message
|
||||||
|
@Test public void resolveException_ShouldReturnRootCheckedExceptionErrorMessage_WhenThereAreCheckedExceptionsChained() throws Exception {
|
||||||
|
TestExceptionWithNoAnnotationAttributes mockException = mock(TestExceptionWithNoAnnotationAttributes.class);
|
||||||
|
TestExceptionWithNoContentStatusCodeAndTextContentType mockCauseException = mock(TestExceptionWithNoContentStatusCodeAndTextContentType.class);
|
||||||
|
doReturn(mockCauseException).when(mockException).getCause();
|
||||||
|
doReturn(new TestExceptionWithNoAnnotation("")).when(mockCauseException).getCause();
|
||||||
|
|
||||||
|
final ExceptionHandler mockAnnotation = mock(ExceptionHandler.class);
|
||||||
|
final HttpServletResponse mockResponse = mock(HttpServletResponse.class);
|
||||||
|
|
||||||
|
final AnnotationHandler sut = spy(new AnnotationHandler());
|
||||||
|
when(sut.getAnnotationFrom(mockCauseException)).thenReturn(mockAnnotation);
|
||||||
|
when(sut.getRootException(mockException, mockException.getCause())).thenReturn(mockCauseException);
|
||||||
|
doReturn(new ModelAndView()).when(sut).handleException(mockAnnotation, mockCauseException, mockResponse);
|
||||||
|
|
||||||
|
final ModelAndView view = sut.resolveException(null, mockResponse, null, mockException);
|
||||||
|
|
||||||
|
verify(sut).handleException(mockAnnotation, mockCauseException, mockResponse); //TestExceptionWithNoContentStatusCodeAndTextContentType
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler()
|
@ExceptionHandler()
|
||||||
@@ -277,5 +307,14 @@ class TestExceptionWithNoContentStatusCodeAndTextContentType extends Exception {
|
|||||||
public TestExceptionWithNoContentStatusCodeAndTextContentType(final String s) {
|
public TestExceptionWithNoContentStatusCodeAndTextContentType(final String s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TestExceptionWithNoContentStatusCodeAndTextContentType(final String s, Throwable ex) {
|
||||||
|
super(s,ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TestExceptionWithNoAnnotation extends Exception {
|
||||||
|
public TestExceptionWithNoAnnotation(final String s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user