보통 백엔드 개발 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를 리턴한다
1.PostNotFound
무언가 삭제하려 할 때 없는 아이디면 서버에서 PostNotFound 에러를 보내준다.
2.InvalidRequest
PostCreate라는 객체에 title 프로퍼티에 "바보" 라는 단어가 들어가면 에러가 발생하게 설정한 상황이다. 적상 작동한다.