I'm trying to show custom error pages depending on the HTTP status code. What I have done is implementing Spring's ErrorController
interface in a CustomErrorController
but it seems that Spring Boot is not recognizing it.
I have followed this tutorial to do that: https://www.baeldung.com/spring-boot-custom-error-page (section 3.1).
There I have read that first you need to get rid of the famous Spring's default Whitelabel Error Page. So I did this:
@SpringBootApplication(exclude = { ErrorMvcAutoConfiguration.class })
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
This seems to work since the Whitelabel error page hasn't appeared anymore but now when an error happens the Apache Tomcat error page (that ugly one with the stack trace included) appears instead of mine.
Then I've just implemented my CustomErrorController
like this:
@Controller
@RequestMapping("/error")
public class CustomErrorController implements ErrorController {
@RequestMapping
public String handleError(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
if (statusCode != null) {
// Specific error page
return "redirect:/error/" + statusCode;
}
// Global error page
return "error/error";
}
@Override
public String getErrorPath() {
return "/error";
}
@GetMapping("/404")
public String notFoundErrorPage() {
return "error/404";
}
// Other error codes mapping methods
}
I'm using Thymeleaf and my error views are under src/main/resources/views/error
, where every specific error page name follows the recommended format of <error_code>.html
so, for instance, a 404 error would have a 404.html
page associated.
I haven't had any problem with other application views resolving so far. Actually, I have configured my Spring Security to call the /error/403
endpoint if access denied occurs and the error page is shown properly.
Same happens with /error/500
, that is called when an internal server exception occurs since I have also implemented the following @ControllerAdvice @ExceptionHandler
method:
@ControllerAdvice
@Log4j2
public class GlobalDefaultExceptionHandler {
@ExceptionHandler(Exception.class)
public String defaultErrorHandler(Exception exception) throws Exception {
if (AnnotationUtils.findAnnotation(exception.getClass(), ResponseStatus.class) != null) {
throw exception;
}
log.catching(exception);
return "redirect:/error/500";
}
}
So, if each of these endpoints works individually, why if Spring throws an error the handleError
method is not called ever?
Thank you.