refactor base smartproc
This commit is contained in:
@ -0,0 +1,49 @@
|
||||
package com.iconplus.smartproc.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@ToString
|
||||
public class BaseException extends RuntimeException {
|
||||
|
||||
protected HttpStatus httpStatus;
|
||||
protected String errorCode;
|
||||
protected String errorDesc;
|
||||
protected String errorMessage;
|
||||
protected String rootCause;
|
||||
protected Map<String, String> errorMessageMap;
|
||||
|
||||
|
||||
public BaseException(HttpStatus httpStatus, String errorCode, String rootCause, String errorDesc, String errorMessage) {
|
||||
super(rootCause);
|
||||
this.httpStatus = httpStatus;
|
||||
this.errorCode = errorCode;
|
||||
this.errorDesc = errorDesc;
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public BaseException(HttpStatus httpStatus, String errorCode, String rootCause) {
|
||||
super(rootCause);
|
||||
this.httpStatus = httpStatus;
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
|
||||
public BaseException(String errorCode, String rootCause) {
|
||||
super(rootCause);
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
|
||||
public BaseException(HttpStatus httpStatus, String errorCode, String rootCause, Map<String, String> errorMessageMap){
|
||||
super(rootCause);
|
||||
this.httpStatus = httpStatus;
|
||||
this.errorCode = errorCode;
|
||||
this.errorMessageMap = errorMessageMap;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.iconplus.smartproc.exception;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class BusinessException extends BaseException {
|
||||
|
||||
public BusinessException(String errorCode, String errorDesc, String errorMessage) {
|
||||
super(HttpStatus.CONFLICT, errorCode, "", errorDesc, errorMessage);
|
||||
}
|
||||
|
||||
public BusinessException(HttpStatus httpStatus, String errorCode, String errorDesc, String errorMessage) {
|
||||
super(httpStatus, errorCode, "", errorDesc, errorMessage);
|
||||
}
|
||||
|
||||
public BusinessException(String errorCode) {
|
||||
super(HttpStatus.CONFLICT, errorCode, "");
|
||||
}
|
||||
public BusinessException(HttpStatus httpStatus, String errorCode) {
|
||||
super(httpStatus, errorCode, "");
|
||||
}
|
||||
|
||||
public BusinessException(String errorCode, Map<String, String> maps) {
|
||||
super(HttpStatus.CONFLICT, errorCode, "", maps);
|
||||
}
|
||||
|
||||
public BusinessException(HttpStatus httpStatus, String errorCode, Map<String, String> maps) {
|
||||
super(httpStatus, errorCode, "", maps);
|
||||
}
|
||||
|
||||
public BusinessException(String errorCode, String rootCause) {
|
||||
super(HttpStatus.CONFLICT, errorCode, rootCause);
|
||||
}
|
||||
|
||||
public BusinessException(HttpStatus httpStatus, String errorCode, String rootCause) {
|
||||
super(httpStatus, errorCode, rootCause);
|
||||
}
|
||||
|
||||
public BusinessException(String errorCode, String rootCause, Map<String, String> maps) {
|
||||
super(HttpStatus.CONFLICT, errorCode, rootCause, maps);
|
||||
}
|
||||
|
||||
public BusinessException(HttpStatus httpStatus, String errorCode, String rootCause, Map<String, String> maps) {
|
||||
super(httpStatus, errorCode, rootCause, maps);
|
||||
}
|
||||
}
|
115
src/main/java/com/iconplus/smartproc/exception/ErrorHelper.java
Normal file
115
src/main/java/com/iconplus/smartproc/exception/ErrorHelper.java
Normal file
@ -0,0 +1,115 @@
|
||||
package com.iconplus.smartproc.exception;
|
||||
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.apache.velocity.Template;
|
||||
import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.app.Velocity;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.runtime.resource.loader.StringResourceLoader;
|
||||
import org.apache.velocity.runtime.resource.util.StringResourceRepository;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import java.io.StringWriter;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.velocity.runtime.RuntimeConstants.RESOURCE_LOADER;
|
||||
|
||||
@Configuration
|
||||
@Log4j2
|
||||
public class ErrorHelper {
|
||||
|
||||
public static final String RAW_TEMPLATE = "rawTemplate";
|
||||
private final VelocityEngine engine;
|
||||
|
||||
public ErrorHelper() {
|
||||
engine = new VelocityEngine();
|
||||
this.addVelocityProperties();
|
||||
engine.init();
|
||||
}
|
||||
|
||||
public ResponseEntity<ErrorResponse> throwErrorException(String errorCode, HttpStatus httpStatus) {
|
||||
|
||||
ErrorResponse errorResponse = new ErrorResponse();
|
||||
errorResponse.setCode(errorCode);
|
||||
errorResponse.setTitle("Kesalahan terjadi");
|
||||
errorResponse.setMessage("Kesalahan terjadi");
|
||||
|
||||
return new ResponseEntity<>(errorResponse, new HttpHeaders(), httpStatus);
|
||||
}
|
||||
|
||||
public ResponseEntity<ErrorResponse> throwErrorExceptionWithHardcodedMsg(String errorCode, HttpStatus httpStatus,
|
||||
String errorDesc, String errorMsg) {
|
||||
|
||||
ErrorResponse errorResponse = new ErrorResponse();
|
||||
errorResponse.setCode(errorCode);
|
||||
errorResponse.setTitle(errorDesc);
|
||||
errorResponse.setMessage(errorMsg);
|
||||
return new ResponseEntity<>(errorResponse, new HttpHeaders(), httpStatus);
|
||||
}
|
||||
|
||||
public ResponseEntity<ErrorResponse> throwErrorExceptionWithMetadata(String errorCode, HttpStatus httpStatus,
|
||||
Map<String, String> metadata) {
|
||||
|
||||
ErrorResponse errorResponse = new ErrorResponse();
|
||||
errorResponse.setCode(errorCode);
|
||||
errorResponse.setTitle("Kesalahan terjadi");
|
||||
errorResponse.setMessage(transform("Kesalahan terjadi", metadata));
|
||||
|
||||
return new ResponseEntity<>(errorResponse, new HttpHeaders(), httpStatus);
|
||||
}
|
||||
|
||||
public ResponseEntity<ErrorResponse> throwErrorExceptionWithMessageAndMetadataWithoutLocalization(HttpStatus httpStatus, String errorCode, String errorTitle, String errorMessage,
|
||||
Map<String, String> metadata) {
|
||||
|
||||
ErrorResponse errorResponse = new ErrorResponse();
|
||||
errorResponse.setCode(errorCode);
|
||||
errorResponse.setTitle(errorTitle);
|
||||
errorResponse.setMessage(transform(errorMessage, metadata));
|
||||
|
||||
return new ResponseEntity<>(errorResponse, new HttpHeaders(), httpStatus);
|
||||
}
|
||||
|
||||
private String transform(String rawNotificationTemplate, Map<String, String> parameters) {
|
||||
|
||||
VelocityContext context = this.getVelocityContext(rawNotificationTemplate, parameters);
|
||||
Template template = engine.getTemplate(RAW_TEMPLATE);
|
||||
|
||||
StringWriter templateWriter = new StringWriter(rawNotificationTemplate.length());
|
||||
template.merge(context, templateWriter);
|
||||
|
||||
return templateWriter.toString();
|
||||
}
|
||||
|
||||
private VelocityContext getVelocityContext(String rawNotificationTemplate, Map<String, String> parameters) {
|
||||
StringResourceRepository resourceRepository = (StringResourceRepository) engine
|
||||
.getApplicationAttribute(StringResourceLoader.REPOSITORY_NAME_DEFAULT);
|
||||
resourceRepository.putStringResource(RAW_TEMPLATE, rawNotificationTemplate);
|
||||
|
||||
return new VelocityContext(parameters);
|
||||
}
|
||||
|
||||
private void addVelocityProperties() {
|
||||
Velocity.addProperty("string.resource.loader.description", "Velocity StringResource loader");
|
||||
|
||||
engine.addProperty(RESOURCE_LOADER, "string");
|
||||
engine.addProperty("string.resource.loader.repository.static", "false");
|
||||
engine.addProperty("string.resource.loader.class",
|
||||
"org.apache.velocity.runtime.resource.loader.StringResourceLoader");
|
||||
engine.addProperty("string.resource.loader.repository.class",
|
||||
"org.apache.velocity.runtime.resource.util.StringResourceRepositoryImpl");
|
||||
engine.setProperty("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.NullLogChute");
|
||||
}
|
||||
|
||||
public ResponseEntity<ErrorResponse> throwErrorExceptionWithMessage(HttpStatus httpStatus, String errorCode, String errorTitle, String errorMessage) {
|
||||
|
||||
ErrorResponse errorResponse = new ErrorResponse();
|
||||
errorResponse.setCode(errorCode);
|
||||
errorResponse.setTitle(errorTitle);
|
||||
errorResponse.setMessage(errorMessage);
|
||||
|
||||
return new ResponseEntity<>(errorResponse, new HttpHeaders(), httpStatus);
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.iconplus.smartproc.exception;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
public class ErrorResponse implements Serializable {
|
||||
private String code;
|
||||
private String title;
|
||||
private String message;
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package com.iconplus.smartproc.exception;
|
||||
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.client.HttpServerErrorException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
@Log4j2
|
||||
@ControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
private ErrorHelper errorHelper;
|
||||
|
||||
public GlobalExceptionHandler(ErrorHelper errorHelper) {
|
||||
this.errorHelper = errorHelper;
|
||||
}
|
||||
|
||||
private Boolean isError = false;
|
||||
private static final String DEFAULT_ERROR_CODE = "80000";
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResponseEntity<ErrorResponse> renderDefaultResponse(Exception ex) {
|
||||
log.error("Exception occurred: ", ex);
|
||||
|
||||
return errorHelper.throwErrorException(DEFAULT_ERROR_CODE, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@ExceptionHandler(BusinessException.class)
|
||||
public ResponseEntity<ErrorResponse> renderBusinessErrorResponse(BusinessException exception) {
|
||||
log.error("BusinessException occurred: ", exception);
|
||||
if (Objects.nonNull(exception.getErrorMessageMap())) {
|
||||
return getErrorResponseResponseEntity(exception.getErrorDesc(), exception.getErrorMessage(), exception.getErrorCode(), exception.getHttpStatus(), exception.getErrorMessageMap());
|
||||
}
|
||||
|
||||
return getErrorResponseResponseEntity(exception.getErrorDesc(), exception.getErrorMessage(), exception.getErrorCode(), exception.getHttpStatus(), null);
|
||||
}
|
||||
|
||||
|
||||
@ExceptionHandler(TechnicalException.class)
|
||||
public ResponseEntity<ErrorResponse> renderTechnicalErrorResponse(TechnicalException exception) {
|
||||
log.error("TechnicalException occurred: ", exception);
|
||||
|
||||
return getErrorResponseResponseEntity(exception.getErrorDesc(), exception.getErrorMessage(), exception.getErrorCode(), exception.getHttpStatus(), null);
|
||||
}
|
||||
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public ResponseEntity<ErrorResponse> renderMethodArgumentErrorResponse(MethodArgumentNotValidException exception) {
|
||||
log.error("MethodArgumentNotValidException occurred: ", exception);
|
||||
|
||||
List<String> errors = new ArrayList<String>();
|
||||
|
||||
for (FieldError error : exception.getBindingResult().getFieldErrors()) {
|
||||
errors.add(error.getField().concat(":").concat(error.getDefaultMessage()));
|
||||
}
|
||||
|
||||
return errorHelper.throwErrorExceptionWithMessage(HttpStatus.BAD_REQUEST, "80400", "Request Validation Error", errors.toString());
|
||||
}
|
||||
|
||||
@ExceptionHandler(HttpServerErrorException.class)
|
||||
public ResponseEntity<ErrorResponse> renderHttpServerErrorResponse(HttpServerErrorException exception) {
|
||||
log.error("HttpServerErrorException occurred: ", exception);
|
||||
|
||||
return errorHelper.throwErrorException(DEFAULT_ERROR_CODE, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@ExceptionHandler(TimeoutException.class)
|
||||
public ResponseEntity<ErrorResponse> renderTimeoutResponse(TimeoutException exception) {
|
||||
log.error("TimeoutException occurred: ", exception);
|
||||
|
||||
return errorHelper.throwErrorException("80001", HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
private ResponseEntity<ErrorResponse> getErrorResponseResponseEntity(String errorDesc, String errorMessage,
|
||||
String errorCode, HttpStatus httpStatus,
|
||||
Map<String, String> metadata) {
|
||||
if (StringUtils.isNotBlank(errorDesc) && StringUtils.isNotBlank(errorMessage)) {
|
||||
|
||||
return errorHelper.throwErrorExceptionWithMessageAndMetadataWithoutLocalization(httpStatus, errorCode, errorDesc, errorMessage, metadata);
|
||||
} else {
|
||||
if (Objects.nonNull(metadata)) {
|
||||
return errorHelper.throwErrorExceptionWithMetadata(errorCode, httpStatus, metadata);
|
||||
}
|
||||
|
||||
return errorHelper.throwErrorException(errorCode, httpStatus);
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean isError() {
|
||||
return isError;
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package com.iconplus.smartproc.exception;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Map;
|
||||
|
||||
@Log4j2
|
||||
@Component
|
||||
public class ResponseExceptionResolver extends AbstractHandlerExceptionResolver {
|
||||
|
||||
private static final String DEFAULT_ERROR_CODE = "80000";
|
||||
|
||||
|
||||
public ResponseExceptionResolver() {}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
protected ModelAndView doResolveException(
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
Object handler,
|
||||
Exception ex
|
||||
) {
|
||||
return handleException(request, response, ex);
|
||||
}
|
||||
|
||||
private ModelAndView handleException(
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
Exception exception
|
||||
) {
|
||||
if (ObjectUtils.isNotEmpty(response) && HttpStatus.UNAUTHORIZED.value() == response.getStatus()
|
||||
&& ObjectUtils.isNotEmpty(exception) && exception instanceof BusinessException
|
||||
) {
|
||||
BusinessException businessException = (BusinessException) exception;
|
||||
ErrorResponse errorResponse = new ErrorResponse();
|
||||
errorResponse.setCode(businessException.getErrorCode());
|
||||
errorResponse.setTitle(businessException.getErrorDesc());
|
||||
errorResponse.setMessage(businessException.getErrorMessage());
|
||||
log.info("Error Response Exception : {}", errorResponse);
|
||||
return new ModelAndView(new MappingJackson2JsonView(), this.getErrorResponse(errorResponse));
|
||||
}
|
||||
response.setHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE);
|
||||
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
|
||||
ErrorResponse errorResponse = new ErrorResponse();
|
||||
errorResponse.setCode(DEFAULT_ERROR_CODE);
|
||||
errorResponse.setTitle("Kesalahan terjadi");
|
||||
errorResponse.setMessage("Kesalahan terjadi");
|
||||
return new ModelAndView(new MappingJackson2JsonView(), this.getErrorResponse(errorResponse));
|
||||
}
|
||||
|
||||
private Map<String, String> getErrorResponse(ErrorResponse errorResponse) {
|
||||
return new ObjectMapper().convertValue(errorResponse, new TypeReference<Map<String, String>>() {
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.iconplus.smartproc.exception;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class TechnicalException extends BaseException {
|
||||
|
||||
public TechnicalException(String errorCode, String errorDesc, String errorMessage) {
|
||||
super(HttpStatus.INTERNAL_SERVER_ERROR, errorCode, "", errorDesc, errorMessage);
|
||||
}
|
||||
|
||||
public TechnicalException(HttpStatus httpStatus, String errorCode, String errorDesc, String errorMessage){
|
||||
super(httpStatus, errorCode, "", errorDesc, errorMessage);
|
||||
}
|
||||
|
||||
public TechnicalException(String errorCode){
|
||||
super(HttpStatus.INTERNAL_SERVER_ERROR, errorCode, "");
|
||||
}
|
||||
|
||||
public TechnicalException(HttpStatus httpStatus, String errorCode){
|
||||
super(httpStatus, errorCode, "");
|
||||
}
|
||||
|
||||
public TechnicalException(String errorCode, String rootCause){
|
||||
super(HttpStatus.INTERNAL_SERVER_ERROR, errorCode, rootCause);
|
||||
}
|
||||
|
||||
public TechnicalException(HttpStatus httpStatus, String errorCode, String rootCause) {
|
||||
super(httpStatus, errorCode, rootCause);
|
||||
}
|
||||
|
||||
public TechnicalException(String errorCode, String rootCause, Map<String, String> maps) {
|
||||
super(HttpStatus.CONFLICT, errorCode, rootCause, maps);
|
||||
}
|
||||
|
||||
public TechnicalException(HttpStatus httpStatus, String errorCode, String rootCause, Map<String, String> maps) {
|
||||
super(httpStatus, errorCode, rootCause, maps);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user