[Trouble Shooting] ExceptionHanlder 예외처리를 통한 원하는 메세지 출력

2022. 12. 11. 00:19Project/시네마그램

Cinemagram 토이 프로젝트를 하다 ExceptionHanlder 예외처리를 통한 메시지 출력 부분에서 에러가 발생했습니다.

해당 부분이 발생한 이유와 해결해나가는 과정을 간단히 정리해보려합니다. 

 

 

 

구현하고 싶은 내용과 예상 결과

  • 회원가입하지 않은 사용자*가 회원정보 변경을 하고 제출 버튼을 클릭을 시
  • Exception이 터지면 ExceptionHandler가 낚아채서 처리
  • 결과적으로 "해당 유저를 찾을 수 없습니다." 메세지를 alert 띄웁니다.
* id = 100을 임의로 기입함
** CustomValidationApiException : 직접 만든 + 유효성 관련 + API 통신 시 사용할 + Exception
*** ControllerExceptionHandler : Controller에서 터지는 Exception은 여기서 다 처리

 

Service > 회원 정보 수정하는 메서드 코드 中 

User userEntity = userRepository.findById(100).orElseThrow(()-> new CustomValidationApiException("해당 유저를 찾을 수 없습니다."));

 

Exception

@Data
@NoArgsConstructor
public class CustomValidationApiException extends RuntimeException {
    private static final long serialVersionUID = 1L;

    private String message;
    private Map<String, String> errors;

    public CustomValidationApiException(String message) {
        super(message);
    }
    
    public CustomValidationApiException(String message, Map<String, String> errors) {
        super(message);
        this.errors = errors;
    }

}

 

ExceptionHandler

@RestController
@ControllerAdvice
public class ControllerExceptionHandler {

    @ExceptionHandler(CustomValidationApiException.class)
    public ResponseEntity<?> validationApiException(CustomValidationApiException e){
        return new ResponseEntity<>(new ResDto<>(-1,e.getMessage(),e.getErrors()), HttpStatus.BAD_REQUEST);
    }
}

 

 

 

현재 상황

 

JS로 Ajax통신시 회원정보 수정 실패하면 error.responseJSON.message를 alert 띄우도록 설계했습니다. 

하지만 개발자도구로 확인한 결과 해당 부분이 null이었습니다. 

 

 

왜 그런걸까?

우선 message가 null인걸 보면 생성자로 전달된 message값이 응답 객체에 세팅이 안 되어진 상황입니다.

 

왜 세팅이 안되어진 걸까요?

 

사실 코드를 작성하면서 약간 찝찝한 부분이 있었습니다. Exception에서 message만 있을 시 생성자를 만든 부분입니다.

public CustomValidationApiException(String message) {
        super(message);
    }

 

super(message)로 전달하면 getMessage()를 통해 값을 가져올 수 있긴 한데, @Data를 썼기에 Getter가 부모 쪽 getMessage()가 아닌 CustomValidationApiException의 getMessage()를 호출합니다.

 

하지만 여기서는 this.messgae로 값 세팅을 안 했으니 당연히 null값인 것이죠.

 

즉, 오버로딩 때 message 값을 세팅 안 해서 생긴 문제였습니다.

 

 

해결 방안

@Data를 삭제하고 생성자로 message 받을 때 this,message에도 세팅을 합니다.

@Getter
@NoArgsConstructor
public class CustomValidationApiException extends RuntimeException {
    private static final long serialVersionUID = 1L;

    private String message;
    private Map<String, String> errors;

    public CustomValidationApiException(String message) {
        this.message = message;
    }
    public CustomValidationApiException(String message, Map<String, String> errors) {
        this.message = message;
        this.errors = errors;
    }
}

 

 

해결 모습

원하는 메시지 경고창이 잘 뜨는 것을 확인했습니다!

 

 

 

 

추가적으로 리팩토링 가능성

부모인 Exception 클래스에 message 필드가 있으므로 message 필드를 아예 빼는 것도 가능합니다.

 

@Data 사용은 자제해야 합니다.

→ 꼭 없애야 하는 부분이므로 토이프로젝트를 진행하면서 하나씩 없앨 예정입니다.