Post

[TIL]커스텀 예외, 처리 너 뭔데

오늘 진행한 작업

🎉완료

  • 회원가입, 관련 예외 처리

🔥진행 중

  • 유저CRUD 테스트 코드

발생한 ISSUE 및 해결 방법

ISSUE1. 예외처리 어디서 어떻게 해….????

문제상황

1
2
3
4
5
6
7
@Transactional
  public void singup(JoinForm joinForm) {
    if (usersRepository.existsByDomainId(joinForm.getId())) {
      throw new UsersException(UserErrorCode.DUPLICATED_ID);
    }
    usersRepository.save(Guardian.createUser(joinForm, passwordEncoder));
  }
  • 이런 식으로 커스텀한 에외를 던지는 건 알겠는데 그럼 그 예외처리는 어디서 어떻게 해야하는거지 라는 의문점이 들었다.
  • 그리고 자바에서 제공해주는 예외가 있는데 왜 예외를 커스텀해서 던질까 하는 생각도 들었다.

해결방법

  • 예외 커스텀하기
    • RuntimeException을 extends해야한다.
    • 컴파일 예외는 프로그램 실행 전에 오류를 고칠 수 있지만 런타임 예외의 경우에는 프로그램 실행중에 발생하기 때문에 미리 예외처리하여 프로그램이 비정상 종료되지 않게 해야한다.
  • 예외처리를 어디서 어떻게 하는지?
    • 저번 관통에서는 try-catch문을 사용하여 예외처리를 해줬었는데 지저분하여 가독성이 좋지 않았다. 이번 기회에 ControllerAdvice를 사용해봤다.

    ControllerAdvice.png

    • 예외처리를 처리하는 곳은 ControllerAdvice이다. @ControllerAdvice를 사용하면 Controller단에서 발생하는 예외들은 모두 이 곳에서 처리가 된다.
      • @ExceptionHandler@ModelAttribute@InitBinder 가 선언된 메서드들에 AOP를 적용해 Controller 단에 적용된다.
    • @RestController를 사용하면 @RestControllerAdvice(@ControllerAdvice,@ResponseBody)를 사용해야 예외를 처리할 수 있고 리턴값으로 ResonseBody를 사용할 수 있다.
  • 커스텀한 예외를 사용하는 이유

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
      @Getter
      @RequiredArgsConstructor
      public enum UserErrorCode {
        
        DUPLICATED_ID(HttpStatus.CONFLICT, "중복된 아이디입니다.");
        
        private final HttpStatus httpStatus;
        private final String message;
        
      }
    
    • 발생한 예외의 구체적인 이유를 예외의 이름으로 지정해서 코드의 가독성을 높일 수 있다.
    • 뷰케어풀 api명세서를 보면 응답코드를 통해 기능이 잘 작동했는지 판단하고 ResponseBody는 사용하지 않았다.
    • 응답코드는 같지만 발생원인은 다를 수 있기 때문에 이유는 메시지에 담아 예외가 터지게 하였다.
    • 또 User관련 에러들을 Enum인 UserErrorCode을 통해
      • 에러의 상태와 행위를 한 곳에 관리 할 수 있다.
      • 명시적으로 예외의 이유를 알 수 있다.

ISSUE2. 하위클래스에서 상위클래스의 속성 빌더가 왜 안돼!!!!

문제상황

  • 추상 상위 클래스로 Users, 구현 하위 클래스로 Guardian, Hospital, CareGiver를 구현했는데 유저가 직접 회원가입하는 행위는 보호자(Guardian)만 하게 된다.
  • 그렇다면 회원가입폼에 입력하는 정보는 보호자의 정보다. 그렇다면 Dto→Entity로 변환할때 Guardian 타입으로 변환해야하는데 그때 빌더를 사용하려고했다.
  • 하위클래스의 공통적인 속성은 유저에 있는데 Guardian에서 빌더를 사용하니 Users의 속성들은 빌더가 생성되지 않았다.

Builder

@Builder를 사용하는 이유

  • 생성자에 파라미터가 많은 경우 가독성이 좋지 않다.
1
2
Users user = new Users("id","password","users1","010-1111-1111"
									,"1996-07-21");
  • 파라미터의 순서를 신경쓰지 않아도 된다.

해결방법

  • @Builder를 @SuperBuilder로 바꾸기
    • @Builder : 어노테이션이 붙은 클래스에 있는 속성만 사용할 수있다.
    • @SuperBuilder : 어노테이션이 붙은 클래스의 상위클래스 속성도 사용할 수 있다.
This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.