Best to extend Spring's ResponseEntityExceptionHandler class and customise it in a way you want, for example:
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import javax.validation.ValidationException;
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(ValidationException.class)
protected ResponseEntity<Object> handle(ValidationException ex) {
return new ResponseEntity<>(getError(HttpStatus.BAD_REQUEST, ex), new HttpHeaders(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler
protected ResponseEntity<Object> handle(Exception ex, WebRequest request) {
try {
return super.handleException(ex, request);
} catch (Exception e) {
return handleExceptionInternal(ex, null, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR, request);
}
}
@Override
protected ResponseEntity<Object> handleExceptionInternal(Exception ex, @Nullable Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
if (HttpStatus.Series.SERVER_ERROR == status.series()) {
log.error("Unexpected error.", ex);
}
return new ResponseEntity<>(getError(status, ex), headers, status);
}
private ApiError getError(HttpStatus status, Exception ex) {
return ApiError.builder()
.status(status.value())
.message(ex.getMessage())
.build();
}
}
This way you can override Spring's default error response body, declare your custom exceptions (e.g. ValidationException) as well as allow Spring to handle its default exceptions declared in ResponseEntityExceptionHandler.
Note although try-catch around super.handleException(ex, request) is not required in Spring 4.x, it is necessary in Spring 5.x due to a change of the underlying ResponseEntityExceptionHandler implementation.
@ControllerAdviceis the way. Why not?ErrorControllerdocs.spring.io/spring-boot/docs/current/api/org/springframework/… which is onle level higher than ControllerAdvice or ExceptionHandler. But not sure if that is what you want@Scheduledto trigger tasks automatically.