Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable redirect to /error for certain urls

I have created a springboot application that contains some Rest API endpoints in .../api/myEndpoints... and thymeleaf templates for some UI forms the user can interact with.

Since I added an errorController:

@Controller
@RequestMapping("/error")
public class ErrorController {

    @RequestMapping(method = RequestMethod.GET)
    public String index(Model model) {
        return "error";
    }
}

whenever an exception is being thrown in my RestControllers, I receive an empty white website containing the word "error". This maybe makes sense for the web frontend, but not for my api. For the API I want spring to output the standard JSON result e.g.:

{
    "timestamp": 1473148776095,
    "status": 400,
    "error": "Bad request",
    "exception": "java.lang.IllegalArgumentException",
    "message": "A required parameter is missing (IllegalArgumentException)",
    "path": "/api/greet"
}

When I remove the index method from the ErrorController, then I always receive the JSON output. My question is: Is it somehow possible to exclude the automatic redirection to /error for all api urls (../api/*) only?

Thanks a lot.

like image 705
user2549803 Avatar asked Sep 06 '16 11:09

user2549803


1 Answers

There may be a better solution out there, until then... here's how you can achieve what you asked:

(1) Disable ErrorMvcAutoConfiguration

Add this to your application.properties:

spring.autoconfigure.exclude: org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration

(2) Define two ControllerAdvices

Since we disabled ErrorMvcAutoConfiguration, we need to catch the exception ourself. Create one advice to catch error for a specific package, and another advice to catch all other. They each redirect to a different url.

//Catch exception for API.
@ControllerAdvice(basePackageClasses = YourApiController.class)
@Order(Ordered.HIGHEST_PRECEDENCE)
public static class ErrorApiAdvice {
    @ExceptionHandler(Throwable.class)
    public String catchApiExceptions(Throwable e) {
        return "/error/api";
    }
}

//Catch all other exceptions
@ControllerAdvice
@Order(Ordered.LOWEST_PRECEDENCE)
public static class ErrorAdvice {
    @ExceptionHandler(Throwable.class)
    public String catchOtherExceptions() {
        return "/error";
    }
}

(3) create a controller to handle the error page

This is where you can have different logic in your error handling:

@RestController
public class MyErrorController {
    @RequestMapping("/error/api")
    public String name(Throwable e) {
        return "api error";
    }

    @RequestMapping("/error")
    public String error() {
        return "error";
    }
}

With Spring-Boot 1.4.x you can also implement ErrorViewResolver (see this doc):

@Component
public class MyErrorViewResolver implements ErrorViewResolver {
    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request,
            HttpStatus status, Map<String, Object> model) {
        if("/one".equals(model.get("path"))){
            return new ModelAndView("/errorpage/api");  
        }else{
            return new ModelAndView("/errorpage");
        }   
    }
}
like image 98
alexbt Avatar answered Sep 18 '22 02:09

alexbt