Spring - 예외처리 직접 만들기

Seongjin Jo·2023년 1월 2일
0

REST API

목록 보기
2/4

💥 예외처리


상황

보통 백엔드 개발 Service 레이어에서 게시글을 기능을 개발한다고 가정하자. 게시글의 특정 id 찾거나 , 수정할 id를 찾거나 , 삭제할 id를 찾을 때 못찾는 경우가 있다. 보통은 못찾으면 컴파일 이후 에러인 RuntimeException 에러가 발생한다. RuntiomeException을 좀 더 Client가 알기 쉽게 상세히 다루기 위해서 직접 클래스를 만들어서 해당하는 특정 에러에 대한 에러메세지를 responsebody에 보낼 수 있다.

우선 RuntimeException에러를 상세히 내 편의에 맞게 다루기 위해서 SeongjnException.class를 만들고 RuntiomeException을 상속한다. 그러고 RuntimeException에서 내가 사용할 메서드를 가져오고 내가 사용할 메서드를 정의해준다.

구현 (예외 처리 방식)

@Getter
public abstract class SeongjinException extends RuntimeException{
    public SeongjinException(String message) {
        super(message);
    }

    public SeongjinException(String message, Throwable cause) {
        super(message, cause);
    }

    private final Map<String,String> validation = new HashMap<>();

    public void addValidation(String fieldName, String message){
        validation.put(fieldName,message);
    }

    public abstract int getStatusCode();
}

1.PostNotFound.class

public class PostNotFound extends SeongjinException{
    private static final String MESSAGE = "존재하지 않는 글입니다.";

    public PostNotFound() {
        super(MESSAGE);
    }

    @Override
    public int getStatusCode(){
        return 404;
    }
}

Service layer에서 id를 찾는 경우 Optional 예외처리

.orElseThrow(() -> new PostNotFound()); 

2.InvalidRequest.class

@Getter
public class InvalidRequest extends SeongjinException{
    private static final String MESSAGE = "잘못된 요청입니다.";

    private String fieldName;
    private String message;

    public InvalidRequest() {
        super(MESSAGE);
    }

    public InvalidRequest(String fieldName, String message){
        super(MESSAGE);
        addValidation(fieldName,message);
    }

    @Override
    public int getStatusCode(){
        return 400;
    }
}

특정 프로퍼티를 invalid할 PostCreate.class에 validate()로 예외처리 선언

    public void validate(){
        if(title.contains("바보")){
            throw new InvalidRequest("title","제목에 바보를 포함할 수 없습니다.");
        }
    }

이런식으로 에러를 설정해주면 ExceptionController에서 설정된 PostNotFound와 InvalidRequest에러가 상속하고 있는 SeongjinException 를 잡아서 response 응답을 해준다.

ExceptionController

    @ResponseBody
    @ExceptionHandler(SeongjinException.class)
    public ResponseEntity<ErrorResponse> SeongjinException(SeongjinException e){
        int statusCode = e.getStatusCode();

        ErrorResponse body = ErrorResponse.builder()
                .code(String.valueOf(statusCode))
                .message(e.getMessage())
                .validation(e.getValidation())
                .build();

        //ResponseEntity를 쓰면 status도 챙기고 , 응답 바디도 챙길 수 있다.
        ResponseEntity<ErrorResponse> response = ResponseEntity.status(statusCode)
                .body(body);

        return response;
    }

이렇게 각 해당하는 에러 정보를 불러와서 에러에 대한 response를 리턴한다

TestCode

1.PostNotFound

무언가 삭제하려 할 때 없는 아이디면 서버에서 PostNotFound 에러를 보내준다.

2.InvalidRequest

PostCreate라는 객체에 title 프로퍼티에 "바보" 라는 단어가 들어가면 에러가 발생하게 설정한 상황이다. 적상 작동한다.

0개의 댓글