문제 상황
- FeignClient 호출 시, 잘못된 입력값(예: 예약 시 잘못된 쿠폰 적용)으로 인해 예외가 발생할 수 있습니다.
- 각 서비스는 자체적인 에러 코드와 메시지를 가지고 있어, 예약 서비스에서 일관되게 예외를 처리하기 어려웠습니다.
- 또한 서비스 전반에서 반복적인 catch 블록이 존재하며, 이는 코드 중복을 발생합니다.
해결 방안
- Feign 클라이언트 관련 예외를 처리할 중앙화된 유틸리티(FeignExceptionUtils)를 생성합니다.
- 예외를 예약 서비스에서 정의한 상태 코드로 래핑 하고, 발생한 에러 메시지(실패 응답에 대한 내용)를 보여줍니다.
- 또한 feignClient 호출 시 예외가 발생할 경우 exception에 따른 catch를 여러 번 반복하며 사용하지 않기 위해 FeignExceptionUtils에 예외 처리 로직을 래핑 하여 간소화합니다.
접근 방식
- 중앙화된 예외 처리:
- 모든 Feign 클라이언트 예외는 catch 블록에서 인터셉트됩니다.
- FeignExceptionUtils.parseFeignException() 사용하여 예외를 처리합니다.
catch (Exception e) { throw FeignExceptionUtils.parseFeignException(e); } - FeignExceptionUtils 구현:
- parseFeignException 메서드는 예외가 FeignException의 인스턴스인지 확인합니다.
- Feign 예외의 경우 응답 본문을 파싱하여 의미 있는 세부 정보(예: 에러 코드 및 메시지)를 추출합니다.
- Feign 이외의 예외에 대해서는 일반적인 에러 메시지를 반환합니다.
public class FeignExceptionUtils { public static FeignClientException parseFeignException(Exception e) { if (e instanceof FeignException) { return handleFeignException((FeignException) e); } else { return new FeignClientException(ErrorCode.UNEXPECTED_ERROR, e.getMessage()); } } private static FeignClientException handleFeignException(FeignException e) { String responseBody = e.contentUTF8(); try { ObjectMapper objectMapper = new ObjectMapper(); JsonNode jsonNode = objectMapper.readTree(responseBody); String message = jsonNode.get("message").asText(); return new FeignClientException(ErrorCode.FEIGN_CLIENT_ERROR, message); } catch (IOException ex) { return new FeignClientException(ErrorCode.GATEWAY_ERROR, responseBody); } } }
느낀 점
- 개발 전 팀원들과 성공응답과 실패응답을 통일했기 때문에 위 코드를 적극 사용하여 재사용성을 높였습니다. 이로 인해 예약 서비스 실행 중 많은 서버가 동작할 텐데 병목 형상이 발생할 경우 어떤 부분에서 예외가 발생한 지 찾는 추적도 쉬웠습니다. 하지만 외부 API을 사용할 경우 응답값이 통일되지 않기 때문에 위 방법을 사용하기는 어려울 것 같습니다.
- 그리고 massage를 String으로 내려주는 것에 대하여 내부적으로 String 값이 변경될 수도 있고, 영어, 일본어 등 다양한 언어를 사용할 경우 메시지가 많아져 관리가 어려울 것 같습니다. 따라서 API 명세서에 상태코드를 정의하고 코드로 이야기하는 것이 올바른 방법 같습니다.
'트러블슈팅' 카테고리의 다른 글
| 실무에서 마주한 LDAP (8) | 2025.08.18 |
|---|---|
| 토큰 검증 오류 (0) | 2024.05.08 |
| 동시성 제어 (0) | 2024.05.08 |
| 스케쥴링 (0) | 2024.04.25 |
| 배포전 로컬 테스트 중 데이터베이스 연결 문제 (0) | 2024.04.19 |