728x90
ApiResponse 를 사용하자 에서 보았듯이 응답의 형태를, 사용하는 프로젝트 요구에 맞게 통일시켜줄 필요가 있다. 이는 Error 에서도 마찬가지이다. 때문에 간단하게 Error 처리를 한번 해보자.
프로젝트에 범용적으로 쓰일 BusinessException 을 만들어보자.
BusinessException 은 RuntimeException 으로 만들것이다.
BusinessException.java
public class BusinessException extends RuntimeException {
private final ErrorCode errorCode;
public BusinessException(ErrorCode errorCode) {
super(errorCode.name());
this.errorCode = errorCode;
}
public BusinessException(String message) {
super(message);
this.errorCode = null;
}
public BusinessException(ErrorCode errorCode, String message) {
super(message);
this.errorCode = errorCode;
}
public ErrorCode getErrorCode() {
return errorCode;
}
public String getErrorMessage() {
return super.getMessage();
}
}
BusinessException 를 만들었기에 BusinessException 를 상속한 커스텀 Error 를 쉽게 생산해 낼 수 있다.
EntityNotFoundException.java
public class EntityNotFoundException extends BusinessException {
public EntityNotFoundException() {
super(ErrorCode.NO_SUCH_ENTITY_ERROR);
}
public EntityNotFoundException(ErrorCode errorCode) {
super(errorCode);
}
public EntityNotFoundException(ErrorCode errorCode, String message) {
super(errorCode, message);
}
public EntityNotFoundException(String message) {
super(message);
}
}
DataNotFoundException.java
public class DataNotFoundException extends BusinessException {
public DataNotFoundException() {
super(ErrorCode.NO_SUCH_DATA_ERROR);
}
public DataNotFoundException(ErrorCode errorCode) {
super(errorCode);
}
public DataNotFoundException(ErrorCode errorCode, String message) {
super(errorCode, message);
}
public DataNotFoundException(String message) {
super(message);
}
}
Spring 에서 API @ExceptionHandler를 처리할 @RestControllerAdvice 를 만들자
ApiExceptionHandler.java
@Slf4j
@RestControllerAdvice
public class ApiExceptionHandler {
private final ApplicationEventPublisher applicationEventPublisher;
@Autowired
public ApiExceptionHandler(final ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
/**
* 사용자의 실수로인한 Error(처리하지 않아도 될)
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler({
BusinessException.class,
DataNotFoundException.class
})
public ApiResponse<String> handleWaning(BusinessException e) {
return handleBusinessException(e, false);
}
/**
* 확인이 필요한 에러(Event를 발생시킬)
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler({
EntityNotFoundException.class
})
public ApiResponse<String> handleCustomException(BusinessException e) {
return handleBusinessException(e, true);
}
private ApiResponse<String> handleBusinessException(BusinessException e, boolean isDataError) {
String errorMessage = isDataError ?
"ApiExceptionHandler > InvalidDataException > exception: {}, {}"
: "ApiExceptionHandler > BusinessException > exception: {}, {}";
log.error(errorMessage, e.getMessage(), e);
ErrorCode ec = e.getErrorCode() == null ? ErrorCode.BAD_REQUEST_ERROR : e.getErrorCode();
String message = e.getMessage();
if (isDataError && e.getErrorCode() != null) {
applicationEventPublisher.publishEvent(new ExceptionEvent(this, message, e));
}
return ApiResponseGenerator.fail(ec, e.getMessage());
}
}
위의 코드를 보면 ApplicationEventPublisher 를 통해 Error 발생에 대한 이벤트를 날리는데, ApplicationEvent 를 상속받은 ExceptionEvent.java 를 만들고 이 Event 를 Listen하는 @EventListener 를 만들어서, Error 발생시 에러에 대한 이벤트를 슬랙 알림 등으로 날려 활용할 수 있다.
728x90
'Project > Table_of_Organization_Management_System' 카테고리의 다른 글
IntelliJ 의 편리한 기능 - 인레이 힌트 (0) | 2022.10.09 |
---|---|
IntelliJ 플러그인을 활용해 마지막 Git 커밋 사용자를 표시해보자 (0) | 2022.08.29 |
Java - Code Convention 설정하기 (0) | 2022.07.05 |
Postman?"No", Http?"Yes" - IntelliJ의 .http를 사용해보자 (0) | 2022.06.17 |
ApiResponse 를 사용하자 (0) | 2022.06.16 |