Exception is not thrown for page doesn't exist - spring

I have defined ExceptionHandler with #ControllerAdvice and catches the following
Exception.class, Throwable.class, SQLException.class
When a user enters a page which doesn't exist or not available in the server. circular view page error is being displayed in the log and ExceptionHandler is not getting called.
What are the usual checkpoints to make the API error to get caught in CustomExceptionHandler. Not sure whether any tomcat hooks to be defined.
Using Spring Boot 2.0 and Spring version 5.0
Thanks.

In case : user enters a page/resource which does not exist, no exception is thrown. So your code does not work (I believe your code is similar to following code)
#ControllerAdvice
public class ErrorHandler {
#ExceptionHandler(Exception.class)
public String handle() {
....
return "error"
}
}
In order to make it work you need to extend yourhandler class from ResponseEntityExceptionHandler as
#ControllerAdvice
public class ErrorHandler extends ResponseEntityExceptionHandler {
...
}
And You need to override the following method
handleHttpMediaTypeNotSupported
handleHttpMediaTypeNotSupported
Detailed guide can be found from
- https://blog.jayway.com/2013/02/03/improve-your-spring-rest-api-part-iii/
- http://www.baeldung.com/global-error-handler-in-a-spring-rest-api
Another way, You can override /error if there is fixed message in all general cases.

Related

spring boot application exception handler which don't have controller

My Spring boot app is standalone application which don't have controller. I am calling service layer from main method of spring boot application.
I have tried to use #ExceptionHandler #ControllerAdvice annotations in my class as below. but control never comes to My Exception Handler method
package com.test.exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
#ControllerAdvice
public class MyExceptionHandler {
#ExceptionHandler(NullPointerException.class)
public void handleNullpointerExcetion() {
System.out.println("Handling Null pointer exception");
}
}
Tried with package name as well which i need to scan in #ControllerAdvice but it is not working
#ControllerAdvice("com.test.utility")
public class MyExceptionHandler {
#ExceptionHandler(NullPointerException.class)
public void handleNullpointerExcetion() {
System.out.println("Handling Null pointer exception");
}
}
Are we not able to handle exception at centralized place if i we don't have controller class which we annotate with #RestContoller or #Controller
I don't think so.
ControllerAdvice is only used whenever a controller would return an exception,
It is a layer that exists after your endpoint in the controller returns and before actually returning the response, to interject and globally handle the exception and is meant to be global only for controllers.
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ControllerAdvice.html
since you don't have a controller, I'd imagine the ControllerAdvice will not help you there.
If you want a centralized error handling mechanism, you'd have to implement something similar to the controller advice yourself around your "Main" function, to which you can have unified exception handling responses.

Difference between AccessDeniedHandler and ResponseEntityExceptionHandler

I am trying to implement CommonExceptionHandler class in my project. I searched on google there are multiple methods to achieve it. The two most common I found are above one. Please help me , When I should use AccessDeniedHandler (Interface) and ResponseEntityExceptionHandler (Class).
Do they make any difference when I enabled Security configuration in the project.?
To make things clear there isn't any relation between ResponseEntityExceptionHandler and AccessDeniedHandler. The 1st one is used to centralized the handling of most common exceptions raised by Spring MVC. It provides about 17 protected methods that you can override to customize the response after the exception. You can find more details here
And example of usage:
#ControllerAdvice // or #RestControllerAdvice
public class CommonExceptionHandler extends ResponseEntityExceptionHandler {
}
Regarding the 2nd one AccessDeniedHandler as indicated on the doc:Handles an access denied failure. An access denied exception is raised when someone try to access a resource which she/he/it is not allowed to access to it.
Now if your question is: Can your CommonExceptionHandler also handle AccessDeniedHandler exception? Yes by doing this:
#ControllerAdvice // or #RestControllerAdvice
public class CommonExceptionHandler extends ResponseEntityExceptionHandler implements AccessDeniedHandler {
}
But I'll suggest you to handle security exception in another class like:
public class CommonSecurityExceptionHandler implements AccessDeniedHandler {
}
I am trying to implement CommonExceptionHandler class in my project.
ResponseEntityExceptionHandler is more preferred because it can handle any sql, javax validation ,http method and any custom exception. It gives you capability to customize error message with status code. Here is an example how you can configure you custom error handler.
As per documenttation, AccessDeniedHandler can handle only exception of type AccessDeniedException. Based on above mentioned link, you can handle AccessDeniedException by just following new method.
#ExceptionHandler(AccessDeniedHandler.class)
#ResponseStatus(value = HttpStatus.CONFLICT)
public Map<String, String> handleAccessDeninedException(AccessDeniedHandler ex) {
// write your own logic to return user friendly response
}

Spring Boot treat 404 as regular exception

Rather than have an error page for a 404 I'd like to treat it like a normal exception in my Spring Boot application. Is there any way to treat the 404 errors as an exception instead of having it forward to the /error page.
My overall goal is basically to treat this using my existing:
#ControllerAdvice
#RestControllerAdvice
public class MyClass {
#ExceptionHandler (...)
public ResponseEntity<?> doStuff(Throwable t) {
// ...
}
}
By default Spring doesn't throw exception when page/resource is not found (NoHandlerFoundException), so there is nothing to handle.
You can override this behaviour by switching this configuration property to true:
spring.mvc.throw-exception-if-no-handler-found=true
After that you can implement your own handler for NoHandlerFoundException.

How exactly work the HandlerExceptionResolver interface in Spring? Can I show an error page when the user try to access to a not mapped resource?

I am studying how to handle custom exception in Spring on a tutorial that show me this class named ExceptionHandler that implement the HandlerExceptionResolver Spring interface:
#Component
public class ExceptionHandler implements HandlerExceptionResolver {
private static final Logger logger = LoggerFactory.getLogger(ExceptionHandler.class);
#Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object object, Exception exception) {
System.out.println("Spring MVC Exception Handling");
logger.error("Error: ", exception);
return new ModelAndView("error/exception","exception","ExceptionHandler message: " + exception.toString());
}
}
And then, into a controller class of the example, it throws this exception in this way:
#RequestMapping(value="/throwRunTimeException", method=RequestMethod.GET)
public void throwException() {
throw new RuntimeException();
}
So I have some doubts about how exactly do this class.
I can't understand if implementing the HandlerExceptionResolver interface I am declaring a new specific exception type or if simply specify a specific behavior that happens when a generic runtime exception is thrown.
It seems me the second situation...I think that, in the previous example, when a generic RuntimeException is thrown it return an exception.jsp page (and the related message that have to be shown into the model object).
So, if the previous assertion is true, can I use this method for the following pourpose?
I think that when a user try to open an URL that is it not mapped to any controller method a RuntimeException is thrown.
So, into the **resolveException()** method, can I extract the required URL from the HttpServletRequest request input parameter and use it to show a specific error message (that indicate that this URL not exist) into the returned view?
I don't think that is possible. When the DispatcherServlet can't find the url mapped in one of your controllers, it will throw a NoHandlerFoundException. This will then be forwarded to your servlet container like Tomcat which handles the error and shows the 404 page for example. You can change this behaviour by adding the following to your web.xml:
`
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/jsp/404error.jsp</location>
</error-page>
`
Note that it's not possible yet to configure this in JavaConfig.
For other Exceptions that are thrown you can use the HandlerExceptionResolver to return the desired view.
You could also use the #ExceptionHandler annotation on a method in your controller to catch the exceptions and handle them appropriately. This can be combined with the #ControllerAdvice annotation to enable this for every controller.

Spring REST API custom exceptions handling

I have a Spring 3.2 application and I've created a REST API based on Spring MVC. I am using #ControllerAdvice annotation for custom exceptions handling. For example:
#ControllerAdvice
public class RestResponseEntityExceptionHandler {
#ExceptionHandler(MyCustomException.class)
#ResponseStatus(HttpStatus.CONFLICT)
#ResponseBody
public ExceptionMessage handleMyCustomException(MyCustomException ex){
return new ExceptionMessage(ex.getClass().getName(), ex.getMessage(), ex.getExceptionCode());
}
}
The issue is that I see how my custom exception is thrown but the exception handler method is actually not being executed and hence my exception message is not returned to the client. Instead, I noticed in the logs how the DefaultHandlerExceptionResolver handles the exception (with a Spring generic one, ServletRequestBindingException in a GET method). How can I get rid of this issue?
Thanks!
The ServletRequestBindingException is a hint that something went wrong before the handler method of the controller. In this case some binding issue.
Exception handlers annotated with #ExceptionHandler are only called when an exception is thrown within a controller handler method (#RequestMapping).

Resources