무지성 RunTimeException은 이제 그만!!

류희수·2024년 10월 29일

미루고 미루어 왔던 공통 예외처리를 적용하려고 한다.

현재까지는 그냥 적당히 RuntimeException으로만 던져주고 메시지만 상세하게 썼는데
프론트 입장에선 보기두 힘들고 코드도 지저분해지는 것 같아 깔끔하게 적용해보려고 한다.


에러

Response 클래스
제네릭 클래스로, 응답 메시지와 결과 값을 함께 관리한다.
공통된 응답을 사용하기 위해 success를 사용하였다.

@RequiredArgsConstructor(access = AccessLevel.PRIVATE): 모든 final 필드를 초기화하는 생성자를 자동으로 생성하지만 PRIVATE 접근 수준을 부여하여, 외부에서 직접 인스턴스를 만들지 못하게 제한하도록 설정


에러코드와, 에러 메시지를 포함한 에러 정보를 담기위한 용도

Message 클래스는 단일 문자열 메시지를 나타내는 용도로 사용되며, 단순한 문자열 데이터를 캡슐화하는 역할을 한다. -> ? 이거 쓰나?

AppException 클래스는 애플리케이션에서 발생하는 예외를 처리하기 위한 커스텀 예외 클래스.
이 클래스는 RuntimeException을 상속받아, 애플리케이션의 실행 중 예외가 발생했을 때 특별한 에러 코드와 메시지를 포함할 수 있게 설계
= 커스텀 예외가 발생할 때 사용한다.

ErrorCode enum 클래스에 설정하였다.
withArgs는 동적으로 메시지를 구성해야 할 떄 사용하고
나머지는 AppException 클래스를 사용하여
고정된 메시지를 사용하기로 하였음.

GlobalExceptionHandler 로 AppException을 전역적으로 처리하기

Spring은 애플리케이션 전체에서 발생한 예외를 감지하여 처리하기 위해 @ControllerAdvice 또는 @RestControllerAdvice에 정의된 메서드를 찾게 된다.

@ControllerAdvice 기능: 모든 컨트롤러에서 발생하는 예외를 처리하거나 공통적인 모델 속성을 추가할 수 있음.

정리

  1. AppException : 예외를 정의하고 발생시키기 위한 클래스.
  • 역할: AppException은 특정 비즈니스 로직에서 예외 상황이 발생했을 때 예외를 정의하고 발생시키기 위해 사용됨.
  • 사용 예: 예를 들어, 사용자가 인증되지 않은 경우 USER_NOT_AUTHORIZED라는 ErrorCode를 포함한 AppException을 발생시킬 수 있다.
  • 어디에서 발생: AppException은 서비스나 도메인 로직에서 발생시킨다!.
  1. GlobalExceptionHandler :
  • 역할: GlobalExceptionHandler는 서비스나 다른 부분에서 발생한 예외를 잡아서 처리하는 클래스.
  • 사용 예: 예를 들어, AppException이 발생하면 GlobalExceptionHandler가 이 예외를 잡아서 클라이언트에 적절한 응답을 돌려주게 된다!
  • 어디에서 처리: 컨트롤러에 도달한 예외를 @ExceptionHandler 메서드들이 처리하게 되는 것!.

적용

변경전 로그인 메소드

변경 후 로그인 메소드 눈으로 보기도 쉬워졌고 무작정
Runtime에러가 나는 게 아닌 상황에 맞는 에러와 메시지가 나오게 된다

withArgs 메소드를 사용하여 동적으로 할당하기

이렇게 중복된 id 같은 값들은 동적으로 알려주는 게 편할 것 같다!

이제 이런식으로 변경해보려고 한다...!
미리미리 했어야 프론트엔드도 편하고 나도 편하고 좋았을 것 같다...!


추가

UserApapter == 가 비어있을 때 예외를 던지는 부분이 매번 컨트롤러에서 반복되는 경우

@RestControllerAdvice
public class GlobalExceptionHandler {

  // AppException 처리
  @ExceptionHandler(AppException.class)
  public ResponseEntity<String> handleAppException(AppException e) {
      HttpStatus status = e.getErrorCode().getHttpStatus();
      String message = e.getErrorCode().getMessage();

      return ResponseEntity.status(status).body(message);
  }

  // UnauthorizedException 처리 
  @ExceptionHandler(UnauthorizedException.class)
  public ResponseEntity<String> handleUnauthorizedException(UnauthorizedException e) {
      return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("인증받지 못한 사용자입니다.");
  }

}

글로벌 익셉션단에서 전부 처리하고 코드상에 로직은 전부 삭제하기!

profile
자바를자바

0개의 댓글