[예외처리] 프론트에게 알려줘야하는 RestTemplate 예외처리

신창호·2024년 3월 23일
0

프로젝트회고

목록 보기
4/8

1️⃣ 서론

백엔드 서버도 외부의 정보가 필요하다면, API를 요청해서 외부정보를 가져올 수 있다. 가장 대표적인 예로 소셜로그인이 있을테고, 콘텐츠 적인 측면으로 공공포털데이터나 라이엇과 같은 데이터(대부분 통계자료)등을 가져올때도 사용할 수 있다.

정보를 가져와서 가공 및 관리는 Backend 서버에서 알아서 처리해가지구 Frontend 서버로 보내주기만 하면 되는 줄 알았다. 굳이 Front단에서 Backend과정까지 노출시킬 필요는 없다고 생각했기때문에, 잘못되면 잘되면 200 OK 잘못되면 Bad Requset만 보내줬다.

당연히 문제발생

  • Backend(나)의 잘못된 판단때문에, 우리 Front 개발자가 고생한 경우가 생겨버렸는데,Bad Requset만 보고 Front단에서 해결할라고 끙끙걸렸다는 것이다..(너무 죄송했다..)
  • 에러를 알아보니, 외부 API에서 404Error로 찾을 수 없는 데이터라고 나왓는데, 이걸 Bad Requset로 처리했으니...뭔가가 잘못 된줄 알았다는 것이다..
  • 이번일을 계기로 외부 API를 사용할때 예외처리도 전부해주는게 좋다 판단하고 다뤄보려고 한다.

2️⃣ RestTemplate 예외처리

RestTemplate이 무엇이냐에 대한 내용은 아래 링크를 참고!

Default 예외처리

  • 대표적으로 RestTemplate에서 제공해주는 에러 핸들링
    • HttpClientErrorException
    • HttpServerErrorException
    • UnknownHttpStatusCodeException

HttpClientErrorException

  • 기본적으로 외부 API로 인한 Client에러처리는 try-catch와 이걸루 처리가 가능하다.
  • e.getStatusCode().is4xxClientError() 으로 4xx 상태코드를 핸들링 할 수 있다.

하지만, 모든 RestTemplate에 대해 이런식으로 핸들링하면, riot Error인지, Discord에러인지, Kakao에러인지 알 수 없다. 그래서 필요한 것이 커스텀 예외처리이다.

커스텀 예외 처리

내가 시도한 커스텀 처리

  • 제공해주는 HttpClientErrorException를 상속받는 자식 class를 만들어 핸들링 해줬다.
  • try-catch문으로 해당 에러를 잡고, 내가 만든 에러로 다시 throw시켜주었다.
  • 그리고, @controllerAdvice에서 @ExceptionHandler(내가만든 에러.class)를 하여 원하는 방식으로 핸들링해 Front에 응답해주는 형식으로 처리해줬다.

내가 쓴 코드 일부

 try {
            ResponseEntity<RiotApiResponseDto.RiotPuuid> response = restTemplate.exchange(ACCOUNT_API_URL, HttpMethod.GET, entity, RiotApiResponseDto.RiotPuuid.class, gameName, gameTag);
            if (response.getStatusCode().is2xxSuccessful()) {
                return response.getBody();
            } else {
                throw new RuntimeException("소환사 정보를 가져오는데 실패했습니다.");
            }
        } 
  } catch (HttpClientErrorException e) {

            if (e.getStatusCode().isSameCodeAs(HttpStatus.NOT_FOUND)) {
                throw new NotFoundRiotClientErrorException(e.getResponseBodyAsString(), e.getStatusCode(), e.getResponseHeaders());
            }
            if (e.getStatusCode().isSameCodeAs(HttpStatus.BAD_REQUEST)) {
                throw new BadRequestRiotClientErrorException(e.getResponseBodyAsString(), e.getStatusCode(), e.getResponseHeaders());
            }
            throw new HttpClientErrorException(e.getStatusCode());
        }

하지만, 이 방법은 내 스스로 생각해본 로직이였고, 이후 알아본 방법으로는 ResponseErrorHandler를 상속받아서 에러를 구현한다고 하니 다음에는 이걸 알아보구 사용해보자!

참고자료

profile
한단계씩 올라가는 개발자

0개의 댓글