Spring @ControllerAdvice vs ErrorController
Asked Answered
C

2

15

In my REST service app, I am planning to create a @ControllerAdvice class to catch controller thrown exceptions and return ResponseEntity objects according to the error type.

But I already have a @RestController class implementing the ErrorController interface to catch all exceptions.

Do these two interfere in any manner? In which cases will ErrorController be called when @ControllerAdvice exists?

Edit: The ErrorController code as requested

@RestController
public class ControllerCustomError implements ErrorController{

    //error json object
    public class ErrorJson {

        public Integer status;
        public String error;
        public String message;
        public String timeStamp;
        public String trace;

        public ErrorJson(int status, Map<String, Object> errorAttributes) {
            this.status = status;
            this.error = (String) errorAttributes.get("error");
            this.message = (String) errorAttributes.get("message");
            this.timeStamp = errorAttributes.get("timestamp").toString();
            this.trace = (String) errorAttributes.get("trace");
        }

    }

    private static final String PATH = "/error";

    @Value("${hybus.error.stacktrace.include}")
    private boolean includeStackTrace = false;

    @Autowired
    private ErrorAttributes errorAttributes;

    @RequestMapping(value = PATH)
    ErrorJson error(HttpServletRequest request, HttpServletResponse response) {
        // Appropriate HTTP response code (e.g. 404 or 500) is automatically set by Spring. 
        // Here we just define response body.
        return new ErrorJson(response.getStatus(), getErrorAttributes(request, includeStackTrace));
    }

    @Override
    public String getErrorPath() {
        return PATH;
    }

    private Map<String, Object> getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) {
        RequestAttributes requestAttributes = new ServletRequestAttributes(request);
        return errorAttributes.getErrorAttributes(requestAttributes, includeStackTrace);
    }
}
Collencollenchyma answered 8/11, 2016 at 14:36 Comment(2)
Add the code for your ErrorControllerHigginbotham
Did you ever find an answer to this question or is it still unsolved? Have you considered adding a bounty?Coco
S
5

An implementation of the ErrorController is used to provide a custom whitelabel error page.

A class annotated with @ControllerAdvise is used to add a global exception handling logic for the whole application. Thus, more than one controller in your application.

If in your application there is no mapping found for a request or page then spring will fallback to the 'whitelabel error page'. And in this case it will be the custom implementation of ErrorController

Spleeny answered 27/1, 2019 at 14:36 Comment(1)
Not quite understand your explanation. Both ErrorController and @ControllerAdvise are used for more than one controller, what's the difference? And second question I'm looking for how to fall back to default white label error page for some conditions (spring profile, status code, etc).Cletus
P
2

In Spring Boot, both ErrorController and @ControllerAdvice are used to handle and customize error responses, but they serve different purposes:

  • ErrorController provides a way to customize error handling for specific error codes or situations and is typically used for handling standard HTTP errors.
  • @ControllerAdvice is used for global exception handling across the application, allowing you to handle custom exceptions and providing consistent responses.

If you have both an implementation of ErrorController and a class annotated with @ControllerAdvice in your Spring Boot application, the @ControllerAdvice will be called first. The order of execution for exception handling in Spring Boot is as follows:

  1. If an exception occurs within a controller method, Spring looks for a suitable @ExceptionHandler method within the same controller to handle that specific exception. If found, the @ExceptionHandler in the controller will be executed.
  2. If no matching @ExceptionHandler is found within the controller, Spring will look for an appropriate @ExceptionHandler method in any class annotated with @ControllerAdvice. If a matching @ExceptionHandler is found in the @ControllerAdvice class, it will be executed.
  3. If no @ExceptionHandler is found in either the controller or the @ControllerAdvice class, Spring will fall back to its default error handling mechanism, which might involve invoking the ErrorController (if implemented) to handle the error.
Plane answered 1/8, 2023 at 18:54 Comment(2)
Thanks Anar, good answer. If it's possible, please, add a best practice suggestion.Seigel
@Seigel I don't think there is any best practice for this, since as my answer suggests, they have slightly different purposes. In general, @ControllerAdvice and @ExceptionHandler should be used in most cases, and ErrorController should only be implemented when you need to customize error handling for cases not covered by @ExceptionHandler methods.Plane

© 2022 - 2024 — McMap. All rights reserved.