DefaultErrorController.java
package access.api;
import access.exception.NotFoundException;
import access.exception.UserRestrictionException;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;
import java.util.List;
import java.util.Map;
import static org.springframework.http.HttpStatus.*;
@RestController
@Hidden
public class DefaultErrorController implements ErrorController {
private static final Log LOG = LogFactory.getLog(DefaultErrorController.class);
private static final List<Class<?>> suppressStackTraceClasses = List.of(
NotFoundException.class
);
private final ErrorAttributes errorAttributes;
@Autowired
public DefaultErrorController(ErrorAttributes errorAttributes) {
this.errorAttributes = errorAttributes;
}
@RequestMapping("/error")
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
WebRequest webRequest = new ServletWebRequest(request);
Map<String, Object> result = this.errorAttributes.getErrorAttributes(
webRequest,
ErrorAttributeOptions.of(
ErrorAttributeOptions.Include.EXCEPTION,
ErrorAttributeOptions.Include.STATUS,
ErrorAttributeOptions.Include.MESSAGE,
ErrorAttributeOptions.Include.BINDING_ERRORS)
);
Throwable error = this.errorAttributes.getError(webRequest);
HttpStatus statusCode;
if (error == null) {
if (result.containsKey("message") && ((String) result.get("message")).equalsIgnoreCase("forbidden")) {
statusCode = FORBIDDEN;
} else {
statusCode = result.containsKey("status") && (int) result.get("status") != 999 ?
HttpStatus.valueOf((int) result.get("status")) : INTERNAL_SERVER_ERROR;
}
} else {
boolean suppressStackTrace = suppressStackTraceClasses.stream().anyMatch(clazz -> clazz.equals(error.getClass()));
LOG.error(String.format("Error occurred: %s", error), suppressStackTrace ? null : error);
if (error instanceof AccessDeniedException) {
statusCode = FORBIDDEN;
} else {
//https://github.com/spring-projects/spring-boot/issues/3057
ResponseStatus annotation = AnnotationUtils.getAnnotation(error.getClass(), ResponseStatus.class);
statusCode = annotation != null ? annotation.value() : BAD_REQUEST;
}
}
result.put("status", statusCode.value());
return ResponseEntity.status(statusCode).body(result);
}
}