java

[java] 커스텀해서 추상화된 예외처리 하기

seulhasony 2023. 8. 17. 13:17

예외처리 또한 서비스 구현만큼 중요합니다.

RuntimeException 에러를 상속받아, http 상태코드와 메세지를 전달받아 보다 명확하게 하겠습니다.

 

가장 익숙하고 빈번한 서비스의 예외처리인 회원가입을 진행하려고 할 경우 발생되는

존재하는 아이디에 대한 예외처리를 커스텀하겠습니다.

 

서비스를 만들면서 수없이 마주할 예외처리들을 넣어두기 위해 exception 패키지를 생성했습니다.

 

그 아래, RuntimeException을 상속받은 추상화된 예외 클래스를 만들었습니다.

http 상태코드와 메세지를 담을 객체를 선언했습니다.

 

AbstractException.java

public abstract class AbstractException extends RuntimeException {
    abstract public int getStatusCode();
    abstract public String getMessage();
}

 

그리고 그걸 상속받은 예외처리 클래스도 생성했습니다.

이렇듯 추상화된 클래스를 만들어 상속받는다면,

존재하는 아이디 예외처리 이외에 원하는 다른 예외처리를 커스텀 할 수 있습니다.

 

AlreadyExistUserException.java

public class AlreadyExistUserException extends AbstractException {
    @Override
    public int getStatusCode() {
        return HttpStatus.BAD_REQUEST.value();
    }

    @Override
    public String getMessage() {
        return "이미 존재하는 아이디입니다.";
    }
}

이제 본인이 만든 메소드에서 에러가 발생했을 경우 어떻게 던질 지를 다룰 수 있는 handler를 만들겠습니다.

거기에 에러가 발생했을 때 던져줄 모델 클래스를 만들어 보다 가독성있게 하겠습니다.

 

CustomExceptionHandler.java

@Slf4j
@ControllerAdvice
public class CustomExceptionHandler {
    @ExceptionHandler(AbstractException.class)
    protected ResponseEntity<ErrorResponse> handleCustomException(AbstractException e){
        ErrorResponse er = ErrorResponse.builder()
                .code(e.getStatusCode())
                .message(e.getMessage())
                .build();

        return new ResponseEntity<>(er, HttpStatus.resolve(e.getStatusCode()));
    }

}

 

ErrorResponse.java

@Data
@Builder
public class ErrorResponse {
    private int code;
    private String message;
}

 

이렇게 해서 필요한 모든 클래스가 생성되었고,

이제 에러가 발생할 예외의 상황에서 적합한 에러 클래스를 호출해주면 됩니다.

이렇게요!

    
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return memberRepository.findByUsername(username)
                            .orElseThrow( () -> new new AlreadyExistUserException());
	}