식당 및 음식 예외 처리 개선

엉금엉금·2022년 7월 9일
0

오늘 만난 문제

목록 보기
11/24

현재 진행 중인 프로젝트에 내가 원하는 로직대로 Exception을 처리해둔 부분이 있지만 그렇지 않은 곳도 있어 한 번 다뤄보려고 한다.

목표

예외 처리 부분을 보기 좋게 고치기
'@ExceptionHandler'를 반드시 사용하기

현재 Exception을 발생시키는 곳

a. 'RestaurantController', 'OrderController'

  • 검증 로직이 실현되는 메서드 (@Valid, @Validated)
  • 이 부분은 'RestaurantControllerAdvice' 라는 'RestControllerAdvice'에서 'MethodArgumentNotValidException' 예외를 받을 경우 JSON 응답을 클라이언트에게 내려준다.
  • 검증 부분은 모두 정상적으로 동작한다.

b. 'RestaurantService', 'FoodService', 'OrderService'

  • RestaurantService
    => 예외 처리가 없다. 음식점의 이름은 중복이 허용된다.
  • FoodService
    => '메뉴 저장' 시 'IllegalArgumentException', 'FoodNameExistException'을 이용하는데 각각 용도는 음식점 조회와 음식 조회이다. 음식점 조회는 음식을 저장하기 위해 우선 음식점을 조회하기 위함이고 음식 조회는 음식명 중복 방지를 위함이다.
  • OrderService
    => '주문 저장' 및 '음식 조회' 시 'NullPointerException'을 발생시킨다.

'FoodService'나 'OrderService'의 Exception이 주된 수정의 대상이 될 것 같다.

'음식점'과 '음식'을 조회 예외 및 변경

기존 예외 발생 부분

throw new FoodNameExistException("name:'" + food.getName() + "'은/는 이미 존재하는 음식명입니다");
Restaurant findRestaurant = restaurantRepository.findById(restaurantId).orElseThrow(
	() -> new IllegalArgumentException("restaurant:존재하지 않는 음식점입니다")
);
restaurantRepository.findById(restaurantId).orElseThrow(
	() -> new NoSuchElementException("해당 음식점이 존재하지 않습니다.")
);
restaurantRepository.findById(restaurantId).orElseThrow(
	() -> new NullPointerException("존재하지 않는 음식점입니다")
);
foodRepository.findById(foodOrderInfo.getId()).orElseThrow(
	() -> new NullPointerException("존재하지 않는 음식입니다")
);
  • 'FoodService'나 'OrderService'에서 발생하는 예외는 음식점과 음식을 조회하는 경우에 발생하는 것이다.

변경 사항

  • 음식 조회 시 예외 클래스 이름 변경

    FoodNameExistException -> FoodAlreadyExistException

읽었을 때 더 확실히 눈에 들어온다는 판한 하에 변경하였다.

  • 그밖에 식당 및 음식 조회 시 존재하지 않는 예외처리
return restaurantRepository.findById(restaurantId).orElseThrow(
	() -> new GlobalExistException("존재하지 않는 음식점입니다")
;
return foodRepository.findById(foodOrderInfo.getId()).orElseThrow(
	() -> new GlobalExistException("존재하지 않는 음식입니다")
;
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(GlobalExistException.class)
public GeneralResponseDto handleGlobalExistException(GlobalExistException e) {
	return new GeneralResponseDto(e);
}

'GlobalExistException'라는 Exception을 상속받는 사용자 정의 클래스를 만들고 위에 보이는 코드의 예처럼 조회 불가 시에 해당 예외를 발생 시키도록 했다. 그리고 'RestControllerAdvice'에 해당 Exception을 처리하고 응답하는 'handleGlobalExistException'이라는 ExceptionHandler 메서드를 두어 클라이언트에 응답하게 처리했다.

결론

우선 진작 이렇게 예외 처리를 해뒀으면 좋았을 걸 하는 생각이 들었다.
위와 같은 예외 처리를 통해서 하나의 컨트롤러에서 상황에 맞게 다양한 응답 처리를 하는 융통성이 생긴 것 같다

profile
step by step

0개의 댓글