API를 작성할 때 따로 Exception Handler를 만들어주지 않으면,
Runtime Error시 모두 500 Error로 Response가 가게 된다.
FE는 이 에러 코드에서 에러에 원인을 알 수 없다.
이를 해결하기 위해 Custome Exception을 추가하여 FE에게 내용을 전달하도록 해보자!
💡 다양한 상황에서 쓰일 Error Code를 만든다.
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;
@AllArgsConstructor
@Getter
public enum ErrorCode {
/* 400 BAD_REQUEST : 잘못된 요청 */
/* 401 UNAUTHORIZED : 인증되지 않은 사용자 */
INVALID_AUTH_TOKEN(HttpStatus.UNAUTHORIZED, "권한 정보가 없는 토큰입니다."),
/* 404 NOT_FOUND : Resource를 찾을 수 없음 */
USER_NOT_FOUND(HttpStatus.NOT_FOUND, "해당하는 정보의 사용자를 찾을 수 없습니다."),
/* 409 : CONFLICT : Resource의 현재 상태와 충돌. 보통 중복된 데이터 존재 */
DUPLICATE_RESOURCE(HttpStatus.CONFLICT, "데이터가 이미 존재합니다."),
;
private final HttpStatus httpStatus;
private final String message;
}
이때, HttpStatus를 따르지 않고
USER_NOT_FOUND(901, "유저 없음")
와 같이 custom해서 만들어도 된다.
다만 이럴 경우에는 HttpStatus타입이 아닌 Integer타입으로 바꿔야 한다!
💡 ErrorCode를 담을 class를 만들자.
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public class CustomException extends RuntimeException{
ErrorCode errorCode;
}
💡 컨트롤러 전역에서 발생하는 Custom에러를 잡아줄 Handler를 만들자
import com.ovcors.godlife.api.exception.CustomException;
import com.ovcors.godlife.api.exception.ErrorResponseEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class CustomExceptionHandler {
@ExceptionHandler(CustomException.class)
protected ResponseEntity<ErrorResponseEntity> handleCustomException(CustomException e) {
return ErrorResponseEntity.toResponseEntity(e.getErrorCode());
}
}
✅ 발생한 CustomException 예외를 잡아서 하나의 메소드에서 공통 처리할 수 있게 해준다.
@ExceptionHandler({ Exception1.class, Exception2.class})
이런식으로 두 개 이상 등록도 가능하다.✅ 모든 컨트롤러에서 발생하는 CustomException을 캐치한다.
✅ Error내용을 담을 Response Entity를 만들어주었다.
@Data
@Builder
public class ErrorResponseEntity {
private int status;
private String code;
private String message;
public static ResponseEntity<ErrorResponseEntity> toResponseEntity(ErrorCode e){
return ResponseEntity
.status(e.getHttpStatus())
.body(ErrorResponseEntity.builder()
.status(e.getHttpStatus().value())
.code(e.name())
.message(e.getMessage())
.build()
);
}
}
userRepository.findById({id}).orElseThrow(
()->new CustomeException(USER_NOT_FOUND)
);
💡 userRepository에서 id에 맞는 유저가 없을 경우 Exception이 발생하여 Response로 전달 될 것이다
이러한 처리를 통해, FE는 에러에 대한 status, code, message를 보고 원인을 정확히 파악할 수 있다.
참고블로그
🔗 https://bcp0109.tistory.com/303
🔗 https://jeong-pro.tistory.com/195
안녕하세요 블로그 잘보고있어요! 혹시 쫌 배울수 있는 기회가 있을까요?