2022. 12. 11. 00:19ㆍProject/시네마그램
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 사용은 자제해야 합니다.
→ 꼭 없애야 하는 부분이므로 토이프로젝트를 진행하면서 하나씩 없앨 예정입니다.
'Project > 시네마그램' 카테고리의 다른 글
[Refactoring] Spring Data JPA Auditing - 시간 한 곳에서 관리 (0) | 2022.12.11 |
---|---|
[Cinemagram] 회원 정보 수정, 필수 값 유효성 검사 및 예외처리 - (5) (1) | 2022.12.11 |
[Cinemagram] 로그인(Spring Security - session 생성) - (4) (0) | 2022.12.07 |
[Cinemagram] 회원가입 유효성 검사(Validation)와 예외처리(ExceptionHandler, @ControllerAdvice) 적용 - (3) (0) | 2022.11.15 |
[Cinemagram] 회원가입 기본 구현 - (2) (0) | 2022.11.13 |