-
NumberFormatException운영 중인 서비스/Coconut. 2024. 1. 23. 15:30
게시글 조회하기 api 작성하면서 테스트 케이스를 적던 중에 만난 이슈입니다.
결론은 NumberFormatException 은 IllegalArgumentException을 상속하고 있다. 입니다 ㅎㅎ
게시글 상세를 가져오는 서비스 코드 입니다.
만약 id가 숫자로 변환이 불가능한 문자열이 들어오는 케이스를 대응하려고 하고 있었습니다.
@Override public PostResDto getPost(String id) { int postId = Integer.parseInt(id); PostResDto dto = new PostResDto(1, "t","t","t","2",1, LocalDateTime.now()); return dto; }
500이 응답으로 올걸 예상하고 포스트맨으로 id에 a를 넣어서 요청을 보냈는데, 400이 응답으로 옵니다.
이상해서 parseInt의 인터페이스를 확인하여보니 NumberFormatException을 예외로 던진다고 나와있습니다.
제가 작성한 글로벌 RestControllerAdvice에는 NumberFormatException을 핸들링하고 있지 않기 때문에 더 당황스러웠습니다.
@Slf4j @RestControllerAdvice public class GlobalExceptionHandler { @ResponseStatus(BAD_REQUEST) @ExceptionHandler(InvalidDataAccessApiUsageException.class) public @ResponseBody HttpErrorInfo handleInvalidDataAccessApiUsageException(WebRequest req, InvalidDataAccessApiUsageException ex) { return createHttpErrorInfo(BAD_REQUEST, req, ex); } @ResponseStatus(BAD_REQUEST) @ExceptionHandler(IllegalArgumentException.class) public @ResponseBody HttpErrorInfo handleIllegalArgumentException(WebRequest req, IllegalArgumentException ex) { return createHttpErrorInfo(BAD_REQUEST, req, ex); } @ResponseStatus(BAD_REQUEST) @ExceptionHandler(MethodArgumentNotValidException.class) public @ResponseBody HttpErrorInfo handleInvalidInputException(WebRequest req, MethodArgumentNotValidException ex) { return createHttpErrorInfo(BAD_REQUEST, req, ex); } @ResponseStatus(INTERNAL_SERVER_ERROR) @ExceptionHandler(Exception.class) public HttpErrorInfo handleAllException(WebRequest req, Exception ex) { return createHttpErrorInfo(INTERNAL_SERVER_ERROR, req, ex); } private HttpErrorInfo createHttpErrorInfo(HttpStatus httpStatus, WebRequest req, Exception ex) { final String path = req.getDescription(false).replace("uri=", "");; final String message = ex.getMessage(); log.debug("Returning HTTP status: {} for path: {}, message: {}", httpStatus, path, message); return new HttpErrorInfo(httpStatus, path, message); } }
혹시 하여 실제로 반환되는 예외도 한번 찍어봅니다.
@Override public PostResDto getPost(String id) { try { int test = Integer.parseInt(id); } catch (Exception ex) { log.info(ex.getClass().getName()); } PostResDto dto = new PostResDto(1, "t","t","t","2",1, LocalDateTime.now()); return dto; }
문서에 적혀있는대로 NumberFormatException을 던져주고 있습니다.
예외 핸들러를 하나씩 주석처리해보면서 확인한 결과 IllegalArgumentException에서 잡히는 걸 확인했습니다.
@ResponseStatus(BAD_REQUEST) @ExceptionHandler(IllegalArgumentException.class) public @ResponseBody HttpErrorInfo handleIllegalArgumentException(WebRequest req, IllegalArgumentException ex) { return createHttpErrorInfo(BAD_REQUEST, req, ex); }
마지막으로 NumberFormatException을 찾아가봤습니다.
이 예외가 IllegalArgumentException을 상속하고 있는 것을 알 수 있습니다.
NumberFortmatException은 별도로 핸들링하지 않는 것으로 결정을 하였습니다~
나중에 더 자세하게 예외 케이스를 알려줘야되면 그 때 추가를 고려해보겠습니다.
업캐스팅 된 데이터의 실제 타입을 확인하려면 아래 방법으로 가능합니다.
data.getClass().getName()
'운영 중인 서비스 > Coconut.' 카테고리의 다른 글
CloudWatch를 사용해서 Discord에서 EC2 상태 알림 받기 (0) 2024.02.16 내 서버는 얼마나 버틸 수 있는가 (0) 2024.02.15 조회수 변경 시 발생하는 레이스 컨디션과 해결 방법 (1) 2024.02.02 String으로 사용되던 데이터 enum으로 상수처리 (0) 2024.01.30 테스트를 쓰면서 만난 좋지 않은 Util 클래스와 의존성관리 (0) 2024.01.25