커스텀 예외(Custum Exception) 사용하기

Daehwan Jung·2023년 1월 16일
0

JAVA

목록 보기
15/15

예외 처리

자바에서는 다양한 형태의 예외 클래스를 제공한다.
하지만 실제 비즈니스 로직에서 발생하는 예외를 제공하진 않기 때문에 예외 클래스를 직접 정의해 사용하는 것이 좋다.

구조


exception 패키지를 만들어서 상황별 에러가 정의될 Enum 형태의 ErrorCode와 RuntimeException을 상속받아서 만든 AppException , 마지막으로 에러를 핸들링 하는 ExceptionManager를 만들어 주었다.

사용자 정의 예외 클래스 작성

AppException

@AllArgsConstructor
@Getter
public class AppException extends  RuntimeException{

    private ErrorCode errorCode;
    private String message;

}

Exception을 상속받아서 일반 예외 클래스로 만드는 방법도 존재하고
RuntimeException을 상속받아서 실행 예외 클래스를 만드는 방법도 존재한다.

ErrorCode

@AllArgsConstructor
@Getter
public enum ErrorCode {

    /**
     *  회원가입 로직 예외
     */
    DUPLICATED_USERID(HttpStatus.CONFLICT,"이미 존재하는 아이디 입니다."),
    NOT_MATCH_PASSWORD(HttpStatus.UNAUTHORIZED, "패스워드가 일치하지 않습니다."),

    /**
     *  로그인 로직 예외
     */
    USERID_NOT_FOUND(HttpStatus.NOT_FOUND, "아이디가 존재하지 않습니다."),
    INVALID_PASSWORD(HttpStatus.UNAUTHORIZED, "패스워드가 잘못되었습니다."),
    INVALID_TOKEN(HttpStatus.UNAUTHORIZED, "잘못된 토큰입니다."),
    private HttpStatus httpStatus;
    private String message;

}

회원가입 로직과 로그인 로직에서 발생할 수 있는 에러들을 정의하였고 나중에 비즈니스 로직이 추가된다면 에러코드도 더 추가될 예정이다.

ExceptionManager

@RestControllerAdvice
public class ExceptionManager {
    @ExceptionHandler(AppException.class)
    public ResponseEntity<?> appExceptionHandler(AppException e){
        return ResponseEntity.status(e.getErrorCode().getHttpStatus())
                .body(e.getErrorCode().name()+ " " +e.getMessage());
    }

}

글로벌 예외처리

@ExceptionHandler
특정 클래스의 메서드에서 Exception핸들링을 하기 위한 어노테이션이다.

@Controller
public class ExceptionController {

    // ...

    @ExceptionHandler(value = RuntimeException.class)
    public ResponseEntity<Object> handle(RuntimeException ex) {
        // ...
    }
}

t

사용법은 위와 같다 하지만 이렇게 되면 해당 Controller에서만 Exception핸들링이 가능하기 때문에 Controller마다 메서드를 작성해 주어야 한다.
이러한 문제를 @ControllerAdvice , @RestControllerAdvice로 해결할 수 있다.

@ControllerAdvice, @RestControllerAdvice
스프링은 @ControllerAdvice와 @RestControllerAdvice라는 어노테이션을 제공한다.
두 어노테이션의 역할은 @Controller 어노테이션이 있는 모든 곳에서의 예외를 처리하게 해준다.
->글로벌 예외 처리
두 어노테이션 차이는 크게 없다. @Controller와 @RestController 와 동일하게 @ResponseBody의 유무 차이만 있을 뿐이다. 그러므로 결과 타입을 Json으로 내려줄지 아니면 View 페이지로 전달할지에 따라서 사용하면 되겠다.

Return 값

return ResponseEntity.status(e.getErrorCode().getHttpStatus())
                .body(e.getErrorCode().name()+ " " +e.getMessage());

코드 그대로 ResponseEntity의 상태에 위에서 커스텀한 ErrorCode의 httpStatus를 넣어주고 body에는 ErrorCode네임과 메세지를 넣어준다.

Not Found

Unatuthorized

Conflict

ErrorCode에서 커스텀한 HTTPSTATUS에 맞게 응답이 오는 걸 확인할 수 있고 Body에도 메세지가 잘 전달된다.

0개의 댓글