All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.zodiac.scaff.crud.web.CommonWebMvcErrorControllerAdvice Maven / Gradle / Ivy

package org.zodiac.scaff.crud.web;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.bind.support.WebExchangeBindException;
import org.springframework.web.server.MethodNotAllowedException;
import org.springframework.web.server.NotAcceptableStatusException;
import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.server.UnsupportedMediaTypeStatusException;
import org.zodiac.authorization.api.exception.AccessDenyException;
import org.zodiac.authorization.api.exception.AuthenticationException;
import org.zodiac.authorization.api.exception.UnauthorizedException;
import org.zodiac.authorization.api.token.TokenState;
import org.zodiac.commons.constants.ResultCodeConstants;
import org.zodiac.commons.exception.HttpNotFoundException;
import org.zodiac.commons.exception.HttpValidationException;
import org.zodiac.reactor.exception.CommonBusinessException;
import org.zodiac.reactor.exception.I18nSupportException;
import org.zodiac.reactor.util.SpringLocaleUtil;

import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;

@Order
@RestControllerAdvice
public class CommonWebMvcErrorControllerAdvice {

    protected final Logger log = LoggerFactory.getLogger(getClass());

    public CommonWebMvcErrorControllerAdvice() {
        super();
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseMessage handleException(CommonBusinessException err) {
        String msg = resolveMessage(err);
        return ResponseMessage.error(err.getStatus(), err.getCode(), msg);
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseMessage handleException(UnsupportedOperationException e) {
        log.error(e.getMessage(), e);
        String msg = resolveMessage(e);
        return ResponseMessage.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), ResultCodeConstants.Error.unsupported, msg);
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public ResponseMessage handleException(UnauthorizedException e) {
        return ResponseMessage
                .error(HttpStatus.UNAUTHORIZED.value(), ResultCodeConstants.Error.unauthorized, resolveMessage(e))
                .result(e.getState());
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public ResponseMessage handleException(AccessDenyException e) {
        return ResponseMessage.error(HttpStatus.FORBIDDEN.value(), e.getCode(), resolveMessage(e));
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ResponseMessage handleException(HttpNotFoundException e) {
        return ResponseMessage.error(HttpStatus.NOT_FOUND.value(), ResultCodeConstants.Error.not_found, resolveMessage(e));
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseMessage> handleException(HttpValidationException e) {
        return ResponseMessage
                .>error(HttpStatus.BAD_REQUEST.value(), ResultCodeConstants.Error.illegal_argument, resolveMessage(e))
                .result(e.getDetails())
                ;
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseMessage> handleException(ConstraintViolationException e) {
        return handleException(new HttpValidationException(e.getConstraintViolations()));
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseMessage> handleException(BindException e) {
        return handleException(new HttpValidationException(e.getMessage(), e
                .getBindingResult().getAllErrors()
                .stream()
                .filter(FieldError.class::isInstance)
                .map(FieldError.class::cast)
                .map(err -> new HttpValidationException.Detail(err.getField(), err.getDefaultMessage(), null))
                .collect(Collectors.toList())));
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseMessage> handleException(WebExchangeBindException e) {
        return handleException(new HttpValidationException(e.getMessage(), e
                .getBindingResult().getAllErrors()
                .stream()
                .filter(FieldError.class::isInstance)
                .map(FieldError.class::cast)
                .map(err -> new HttpValidationException.Detail(err.getField(), err.getDefaultMessage(), null))
                .collect(Collectors.toList())));
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseMessage> handleException(MethodArgumentNotValidException e) {
        return handleException(new HttpValidationException(e.getMessage(), e
                .getBindingResult().getAllErrors()
                .stream()
                .filter(FieldError.class::isInstance)
                .map(FieldError.class::cast)
                .map(err -> new HttpValidationException.Detail(err.getField(), err.getDefaultMessage(), null))
                .collect(Collectors.toList())));
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseMessage handleException(javax.validation.ValidationException e) {
        return ResponseMessage.error(HttpStatus.BAD_REQUEST.value(), ResultCodeConstants.Error.illegal_argument, e.getMessage());
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.GATEWAY_TIMEOUT)
    public ResponseMessage handleException(TimeoutException e) {
        return ResponseMessage.error(HttpStatus.GATEWAY_TIMEOUT.value(), ResultCodeConstants.Error.timeout, resolveMessage(e));
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @Order
    public ResponseMessage handleException(RuntimeException e) {
        log.error(e.getMessage(), e);
        return ResponseMessage.error(resolveMessage(e));
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseMessage handleException(NullPointerException e) {
        log.error(e.getMessage(), e);
        return ResponseMessage.error(e.getMessage());
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseMessage handleException(IllegalArgumentException e) {
        log.error(e.getMessage(), e);
        return ResponseMessage.error(HttpStatus.BAD_REQUEST.value(), ResultCodeConstants.Error.illegal_argument, resolveMessage(e));
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseMessage handleException(AuthenticationException e) {
        log.error(e.getLocalizedMessage(), e);
        return ResponseMessage.error(HttpStatus.BAD_REQUEST.value(), e.getCode(), resolveMessage(e));
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    public ResponseMessage handleException(UnsupportedMediaTypeStatusException e) {
        log.error(e.getLocalizedMessage(), e);
        return ResponseMessage
                .error(HttpStatus.UNSUPPORTED_MEDIA_TYPE.value(), "unsupported_media_type", SpringLocaleUtil.resolveMessage("error.unsupported_media_type"))
                .result(e.getSupportedMediaTypes());
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
    public ResponseMessage handleException(NotAcceptableStatusException e) {
        log.error(e.getMessage(), e);
        return ResponseMessage
                .error(HttpStatus.NOT_ACCEPTABLE.value(), "not_acceptable_media_type", SpringLocaleUtil
                        .resolveMessage("error.not_acceptable_media_type"))
                .result(e.getSupportedMediaTypes());
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
    public ResponseMessage handleException(MethodNotAllowedException e) {
        log.error(e.getMessage(), e);
        return ResponseMessage
                .error(HttpStatus.NOT_ACCEPTABLE.value(), "method_not_allowed", SpringLocaleUtil.resolveMessage("error.method_not_allowed"))
                .result(e.getSupportedMethods());
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseMessage> handleException(ServerWebInputException e) {
        Throwable exception = e;
        do {
            exception = exception.getCause();
            if (exception instanceof HttpValidationException) {
                return handleException(((HttpValidationException) exception));
            }

        } while (exception != null && exception != e);
        if (exception == null) {
            return  ResponseMessage.error(HttpStatus.BAD_REQUEST.value(), ResultCodeConstants.Error.illegal_argument, e.getMessage());
        }
        return ResponseMessage.error(HttpStatus.BAD_REQUEST.value(), ResultCodeConstants.Error.illegal_argument, resolveMessage(exception));
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseMessage handleException(I18nSupportException e) {
        return ResponseMessage.error(HttpStatus.BAD_REQUEST.value(), e.getI18nCode(), resolveMessage(e));
    }

    private String resolveMessage(Throwable e) {
        if (e instanceof I18nSupportException) {
            return SpringLocaleUtil.resolveMessage(((I18nSupportException) e).getI18nCode());
        }
        return e.getMessage() == null ? null : SpringLocaleUtil.resolveMessage(e.getMessage());
    }

}