I want to catch an Error in springMVC3 using exception handler. I annotated the exception. I can catch throwable and any exception. But when I tried with Error, It is not catching the exception. Any idea why it is so? The below code catches exceptions
ExceptionHandler(InvalidDataException.class)
public ModelMap handleException(InvalidDataException ex) {
logger.debug("exception catched :" + ex);
return new ModelMap();
}
But the below is not catching;
#ExceptionHandler(Error.class)
public ModelMap handleException(Error ex) {
logger.debug("exception catched :" + ex);
return new ModelMap();
}
The second example is not working because you are catching an Error, which extends Throwable and not Exception. You will find that the code will work if you change to the '#ExceptionHandler' and the 'handleException()' method to either 'Exception', 'InvalidDataException' or any other exception that is of interest.
Even I too faced the same problem ,I think #ExceptionHandler can deal with exceptions only not with throwable and errors
Refer the link:ExceptionHandler doesn't work with Throwable
Related
When I am calling save() of JPA it is giving exception of ConstraintViolation exception but it is inside nested exception.
First one is IllegalStateException, then NestedServletException, DataIntegrotyViolationException, ConstraintViolationException, SQLServerException
There
com.microsoft.sqlserver.jdbc.SQLServerException: Violation of UNIQUE KEY constraint 'uk_urmapping_uname_role'. Cannot insert duplicate key in object 'dbo.employee_role_mapping'. The duplicate key value is (wxy ., ABC).
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:259) ~[mssql-jdbc-6.4.0.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1547) ~[mssql-jdbc-6.4.0.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:548) ~[mssql-jdbc-6.4.0.jre8.jar:na]
In CustomExceptionHandler class I added
#ExceptionHandler({ GenericJDBCException.class, SQLException.class, DuplicateKeyException.class,
ConstraintViolationException.class, JDBCException.class })
public ResponseEntity<Object> processSqlExceptions(SQLException e, WebRequest request) {
logger.error("SQL Error : ", e);
logger.warn("SQL Error : ", e);
ErrorResponse error = new ErrorResponse("600", e.getMessage(), tracer.currentSpan().context().spanIdString());
return handleExceptionInternal(e, error, new HttpHeaders(), HttpStatus.BAD_REQUEST, request);
}
I tried to handle some exception, still it is not able to handle exception.
It is a DataIntegrityViolationException so you should have it added in the handler.
#ExceptionHandler(value = {DataIntegrityViolationException.class})
If you use hibernate then it throws it's own version of ConstraintViolationException.
So make sure you handle org.hibernate.exception.ConstraintViolationException instead of javax.validation.ConstraintViolationException (or both).
I am trying to catch an exception in order to evaluate and see which request from the front-end caused it. However, my breakpoint is never triggered:
try{
filterChain.doFilter(request, response);
}catch(Exception e){
if(e instanceof org.springframework.web.HttpRequestMethodNotSupportedException)
throw new HttpRequestMethodNotSupportedException(e.getMessage());
throw new RuntimeException(e);
}
Any reason why my breakpoint inside the catch statement is never executed? The stacktrace denotes this specific method as the source of the exception.
The answer was provided by #M. Deinum :
Because the DispatcherServlet itself is handling the exception. From
the perspective of the filter there is no exception.
So I am trying to log all uncaught exceptions returned by the controllers of a spring project in a generic fashion.
I was able to do this with the following exception handler:
#ControllerAdvice
public class ControllerConfig {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
public static final String DEFAULT_ERROR_VIEW = "error";
#ExceptionHandler(HttpMessageNotReadableException.class)
#ResponseStatus(HttpStatus.BAD_REQUEST)
public void handleBadRequest(HttpMessageNotReadableException e) {
logger.warn("Returning HTTP 400 Bad Request", e);
throw e;
}
#ExceptionHandler(AccessDeniedException.class)
public void defaultErrorHandler(HttpServletRequest request, Exception e) throws Exception {
logger.error("Error in request:" + request.getRequestURL(), e);
throw e;
}
This also returns the error responses of the request, so I don't have to differentiate between all the different error response codes.
However, for every invocation of the method a second error log is created because of the exception thrown in the method:
Code is from org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#doResolveHandlerMethodException
try {
if (logger.isDebugEnabled()) {
logger.debug("Invoking #ExceptionHandler method: " + exceptionHandlerMethod);
}
exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, exception);
}
catch (Exception invocationEx) {
if (logger.isErrorEnabled()) {
logger.error("Failed to invoke #ExceptionHandler method: " + exceptionHandlerMethod, invocationEx);
}
return null;
}
So is there a smarter way to return the original exception of the method?
It depends on what do you mean by "a smarter way to return the original exception". What exactly would you like to return to the client? If this is just the message of the exception you can simply return it from the exception handler and annotate the method with #ResponseBody. Spring will do the rest for you.
#ExceptionHandler(HttpMessageNotReadableException.class)
#ResponseStatus(HttpStatus.BAD_REQUEST)
#ResponseBody
public String handleBadRequest(HttpMessageNotReadableException e) {
logger.warn("Returning HTTP 400 Bad Request", e);
throw e.getMessage();
}
You can also return some custom object which wraps the exception information and any other data that you desire.
I am using spring's #ControllerAdvice and #ExceptionHandler for exception handling.
Any method throws custom exception from Controller and corresponding #ExceptionHandler handle it. If Runtime exception occurs(eg any HibernateException) then it will throw Runtime Exception and I dont have any #ExceptionHandler for RuntimeExceptions.
My question is how to handle any runtime exception? do I need to add #ExceptionHandler for every Exception that is thrown by controller?
I dont want create an Generic ExceptionHandler for Exception.class because I have to send different error code according to exception occured.
one way to do it add try catch block in Controller and then throw the custom exception from catch block?
or is there any another better way?
All #ExceptionHandlers are inside #ControllerAdvice class.
the alternative is don't catch Exception in Controller. catch all Exception in service layer and throw a custom Exception eg. if you persisting a record failed, throw DatabaseException with message. see below method:
Student persist(Student object){
try{
studentDao.insert(object);
}catch(HibernateException e){
throw new DatabaseException("database operation failed!");
}
return student;
}
from you exception handler method you can get the message. this way you can set different message on different Exception.
I've extended WebApplicationException with an UnauthorizedException:
public class UnauthorizedException extends WebApplicationException {
My REST classes extend a base class that implements the authCheck, a subclass method:
try{
authCheck();
RecordingList recordings = CODIRecording.getRecordings(type, timeframe);
return Response.ok().entity(recordings).build();
}catch(WebApplicationException e){
throw e; // Results in 500
throw new UnauthorizedException(); // Results in 401
}
When the authCheck fails it throws UnauthorizedException. If the subclass method doesn't have the catch/try (the exception just propagates out from authCheck) or if it re-throws the exception the client receives a 500.
If the method's catch throws a NEW UnauthorizedException the client receives a 401 as expected.
Is this "normal" behavior? It seems odd.
I would guess that what you are actually catching there is not UnauthorizedException, but some other WebApplicationException. Did you try debugger? Or simply do e.printStackTrace() in the catch clause to be sure.