0

I am trying to create my own custom response for all types of RestClientResponseException in my Spring Boot Application

Custom exception thrown from Controller class :

throw new HealthCheckRestException(ex.getResponseBodyAsString());

My ExceptionHandler class goes like this :

@Order(Ordered.HIGHEST_PRECEDENCE)
@EnableWebMvc
@ControllerAdvice
public class AvailExceptionHandler {

private static final Logger logger = Logger.getLogger(AvailExceptionHandler.class);

@ExceptionHandler(value=HealthCheckRestException.class)
    public AvailResponse handleHttpErrorResponse(final HealthCheckRestException ex, final HttpServletRequest request){
        logger.error("RestClientException is thrown from HealthCheck API: with status :"
                + ex.getStatusText() + " and exception : "+ ex.getMessage());
        return new AvailResponse(AvailStatus.ERROR);
    }
}

I have tried all possible cases like :

1) Trying @ExceptionHandler inside the controller class
2) Including @ControllerAdvice(basePackages = "com.org.availabillity.utilities") to scan for specific packages where the controller is defined.
3) Using @Order(Ordered.HIGHEST_PRECEDENCE) to set precedence
4) Using @RestControllerAdvice

Nothing seems to intercept after the exception is thrown and call the method annotated with @ExceptionHandler

Stuck for sometime now on this and need some help. Much appreciate your help on this.

I am using spring-web-5.0.6.RELEASE
sayak
  • 3
  • 2

2 Answers2

0

Try with something like this:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import java.util.Map;

@RestControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public final class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
  private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

  private static final boolean INCLUDE_STACKTRACE = false;

  @ExceptionHandler(Exception.class)
  public ResponseEntity<Map<String, Object>> handle(final WebRequest request, final Throwable exception) {
    log.debug("Fallback handler executed for unhandled exception:", exception);
    return new ResponseEntity<>(new DefaultErrorAttributes().getErrorAttributes(request, INCLUDE_STACKTRACE),
        HttpStatus.INTERNAL_SERVER_ERROR);
  }

  // IllegalArgumentException is not "entirely correct", so replace this with your own
  @ExceptionHandler(IllegalArgumentException.class)
  public ResponseEntity<Map<String, Object>> handle1(final WebRequest request, final Throwable exception) {
    log.debug("Fallback handler executed for unhandled exception:", exception);
    return new ResponseEntity<>(new DefaultErrorAttributes().getErrorAttributes(request, INCLUDE_STACKTRACE),
        HttpStatus.INTERNAL_SERVER_ERROR);
  }

  // TODO: Keep adding exception(s) handlers for particular cases
}

GlobalExceptionHandler is just a Spring component/bean that can be placed anywhere, provided you configured that location to be discovered.

@EnableWebMvc should be placed in a class annotated with @Configuration. Moreover, if you are using Spring Boot, chances are you don't need it because it will be inferred.

x80486
  • 6,627
  • 5
  • 52
  • 111
0

Here is the small example from my Handler class;

@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler({QueryNotFoundException.class,ContentNotAllowedException.class})
public final ResponseEntity<ApiError> handleException(Exception ex, WebRequest request) {
    HttpHeaders headers = new HttpHeaders();

    if (ex instanceof QueryNotFoundException) {
        HttpStatus status = HttpStatus.NOT_FOUND;
        QueryNotFoundException qnfe = (QueryNotFoundException) ex;
        return handleQueryNotFoundException(qnfe, headers, status, request);
     } else if (ex instanceof ContentNotAllowedException) {
        HttpStatus status = HttpStatus.BAD_REQUEST;
        ContentNotAllowedException cnae = (ContentNotAllowedException) ex;
        return handleContentNotAllowedException(cnae, headers, status, request);
    } else {
        HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
        return handleExceptionInternal(ex, null, headers, status, request);
    }
Habil
  • 540
  • 1
  • 8
  • 20