How to rethrow exception as @ResponseStatus-annotated exception in Spring @ExceptionHandler?
exception, java, spring, spring-mvc
Solution
Instead of throwing an exception try this:
@ExceptionHandler( value=ArticleNotFoundException.class )
public ResponseEntity<String> handleArticleNotFound() {
return new ResponseEntity<String>(HttpStatus.NOT_FOUND);
}
This will basically return a Spring object that gets converted into a 404 by your controller.
You can pass it a different HttpStatus if you want to return different HTTP status messages to your front-end.
If you are deadset on doing this with annotations, just annotate that controller method with @ResponseStatus and don't throw an exception.
Basically if you annotate a method with `@ExceptionHandler` I'm 90% sure that Spring expects that method to consume that exception and not throw another one. By throwing a different exception, Spring thinks that the exception wasn't handled and that your exception handler failed, hence the message in your logs
EDIT:
To get it to return to a specific page try
return new ResponseEntity<String>(location/of/your/page.html, HttpStatus.NOT_FOUND);
EDIT 2: You should be able to do this:
@ExceptionHandler( value=ArticleNotFoundException.class )
public ResponseEntity<String> handleArticleNotFound(HttpServletResponse response) {
response.sendRedirect(location/of/your/page);
return new ResponseEntity<String>(HttpStatus.NOT_FOUND);
}
Problem
I have made exception, that I'm throwing always when I want a 404 page: ``` @ResponseStatus( value = HttpStatus.NOT_FOUND ) public class PageNotFoundException extends RuntimeException { ``` I want to create controller-wide `@ExceptionHandler` that will re-throw `ArticleNotFoundException`(which causes error 500) as my 404 exception: ``` @ExceptionHandler( value=ArticleNotFoundException.class ) public void handleArticleNotFound() { throw new PageNotFoundException(); } ``` But it doesn't work - I still have error 500 and Spring logs: `ExceptionHandlerExceptionResolver - Failed to invoke @ExceptionHandler method: ...` Note that I translate code to html so response cannot be empty or simple String like with `ResponseEntity`. `web.xml` entry: ``` <error-page> <location>/resources/error-pages/404.html</location> <error-code>404</error-code> </error-page> ``` FINAL SOLUTION FROM ANSWER COMMENTS It's not a full re-throw, but at least it uses `web.xml` error page mapping like my `PageNotFoundException` ``` @ExceptionHandler( value = ArticleNotFoundException.class ) public void handle( HttpServletResponse response) throws IOException { response.sendError( HttpServletResponse.SC_NOT_FOUND ); } ```