WebExceptionAspect.java
package io.featureprobe.api.aop;
import io.featureprobe.api.base.constants.MessageKey;
import io.featureprobe.api.base.constants.ResponseCode;
import io.featureprobe.api.base.exception.ForbiddenException;
import io.featureprobe.api.base.model.BaseResponse;
import io.featureprobe.api.base.util.JsonMapper;
import io.featureprobe.api.component.I18nConverter;
import io.featureprobe.api.dao.exception.ResourceConflictException;
import io.featureprobe.api.dao.exception.ResourceNotFoundException;
import io.featureprobe.api.dao.exception.ResourceOverflowException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import javax.persistence.OptimisticLockException;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@AllArgsConstructor
@ControllerAdvice
@Slf4j
public class WebExceptionAspect {
I18nConverter i18nConverter;
@ExceptionHandler(value = ResourceNotFoundException.class)
public void resourceNotFoundHandler(HttpServletResponse response, ResourceNotFoundException e)
throws IOException {
response.setStatus(HttpStatus.BAD_REQUEST.value());
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
String resourceNameMessage = i18nConverter.getResourceNameMessage(e.resourceType);
String resourceNotFoundMessage = i18nConverter.get(ResponseCode.NOT_FOUND.messageKey(),
new Object[]{resourceNameMessage, e.resourceKey});
response.getWriter().write(toErrorResponse(ResponseCode.NOT_FOUND, resourceNotFoundMessage));
}
@ExceptionHandler(value = ResourceOverflowException.class)
public void resourceOverflowHandler(HttpServletResponse response, ResourceOverflowException e)
throws IOException {
response.setStatus(HttpStatus.BAD_REQUEST.value());
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
String resourceNameMessage = i18nConverter.getResourceNameMessage(e.resourceType);
String resourceOverflowMessage = i18nConverter.get(ResponseCode.NOT_FOUND.messageKey(),
new Object[]{resourceNameMessage});
response.getWriter().write(toErrorResponse(ResponseCode.OVERFLOW, resourceOverflowMessage));
}
@ExceptionHandler(value = ResourceConflictException.class)
public void resourceConflictHandler(HttpServletResponse response)
throws IOException {
response.setStatus(HttpStatus.BAD_REQUEST.value());
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.getWriter().write(toErrorResponse(ResponseCode.CONFLICT));
}
@ExceptionHandler(value = ForbiddenException.class)
public void forbiddenHandler(HttpServletResponse response, ForbiddenException e)
throws IOException {
response.setStatus(HttpStatus.FORBIDDEN.value());
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.getWriter().write(toErrorResponse(ResponseCode.FORBIDDEN));
}
@ExceptionHandler(value = {IllegalArgumentException.class, OptimisticLockException.class})
public void invalidArgumentHandler(HttpServletResponse response, RuntimeException e)
throws IOException {
response.setStatus(HttpStatus.BAD_REQUEST.value());
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
String messageKey = e.getMessage();
if (e instanceof OptimisticLockException) {
messageKey = MessageKey.CONFLICT_REQUEST;
}
response.getWriter().write(toErrorResponse(ResponseCode.INVALID_REQUEST, i18nConverter.get(messageKey)));
log.warn("invalidArgumentHandler", e);
}
private String toErrorResponse(ResponseCode resourceCode) {
return toErrorResponse(resourceCode, i18nConverter.get(resourceCode.messageKey()));
}
private String toErrorResponse(ResponseCode responseCode, String message) {
return JsonMapper.toJSONString(new BaseResponse(responseCode.code(), message));
}
}