배경
- MSA로 프로젝트를 구성하면서 서비스간 통신시 여러 예외가 발생
- RuntimeException에 잡히지 않는 checked exception을 어떻게 다룰지에 대한 고민이 생김
문제상황
- 카프카 이벤트를 역직렬화 하는 과정에서 JsonProcessingException이 발생할 수 있어 예외가 발생하면 throw 하도록 처리
- 예외가 발생했을때 예외가 상위 메서드로 전파되고 있어 json 파싱 실패한 곳에서 바로 확인이 어려움
public void handleSubmissionEvent(String message) throws JsonProcessingException {
KafkaMessage kafkaMessage = objectMapper.readValue(message, KafkaMessage.class);
SubmissionKafkaEvent event = objectMapper.readValue( // payload 역직렬화
kafkaMessage.getPayload(),
SubmissionKafkaEvent.class
);
event.setMessageId(kafkaMessage.getMessageId());
notificationService.createNotificationFromSubmissionEvent(event);
}
해결방안
- Checked Exception이 발생할 수 있는 지점에서 try-catch로 즉시 처리
- 발생한 예외를 시스템에서 정의한 GlobalException으로 변환하여 일관된 예외 처리
시도
- JsonProcessingException을 try-catch문 안에 넣어서 json 파싱 실패 시점에 에러를 바로 처리하도록 개선
- 메서드 시그니처에서 구현 세부사항인 JsonProcessingException이 제거되어 캡슐화가 향상됨
public void handleSubmissionEvent(String message) {
try {
KafkaMessage kafkaMessage = objectMapper.readValue(message, KafkaMessage.class);
SubmissionKafkaEvent event = objectMapper.readValue( // payload 역직렬화
kafkaMessage.getPayload(),
SubmissionKafkaEvent.class
);
event.setMessageId(kafkaMessage.getMessageId());
notificationService.createNotificationFromSubmissionEvent(event);
} catch (JsonProcessingException e) {
log.error("Failed to process kafka message: {}", message, e);
throw new GlobalException(ErrorCode.EXTERNAL_SERVICE_ERROR, e.getMessage());
}
}
결과
- 예외 발생 시점에 즉시 처리함으로써 문제 추적이 용이해짐
- 시스템 전반에서 일관된 예외 처리 방식 적용 가능