ResponseEntity를 통해 404 상태 코드와 함께 메시지를 반환하도록 처리
// 컨트롤러
try {
PostResponseDTO postDto = boardService.findById(postId);
return ResponseEntity.ok(postDto);
} catch (NoSuchElementException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("게시글을 찾을 수 없습니다.");
}
// 서비스
Optional<Post> postOptional = postRepository.findById(postId);
Post post = postOptional.orElseThrow(() -> new NoSuchElementException("게시글을 찾을 수 없습니다."));
NoSuchElementException
은 Java에서 원소를 찾을 때 해당 원소가 없을 경우 발생하는 예외입니다.
💡 전역 에러 핸들러(Global Exception Handler) 란?
HTTP Status 코드로 정상코드가 아닌오류코드
로 반환하였을 시 실제에러
가 발생하기에 이를 위해 중간에 GlobalExcpetion을 통해 Exception 발생 시에도 HTTP Status 코드로정상 코드
를 보내고 커스텀한 코드를 보냄으로써 실제 Client 내에서 이를 처리할 수 있게 돕기 위함입니다.
@ControllerAdvice
Service
에서 예외가 발생하더라도 잡아낸다@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(NoSuchElementException.class)
public ResponseEntity<String> handleNoSuchElementException(NoSuchElementException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("게시글을 찾을 수 없습니다.");
}
}
// service
private Post returnPost(Long postId) {
return boardRepository.findById(postId)
.orElseThrow(NoSuchElementException::new);
}
해당 예외가 발생하면 클라이언트에게 NOT_FOUND(404) 상태 코드와 함께 예외 메시지를 반환합니다.
@RestControllerAdvice
@ExceptionHandler
표준 예외를 적극적으로 사용하자
커스텀 예외의 이름만 봐도 어떤 예외인지 알아볼 수 있다. 하지만 표준 예외를 사용하고 errorMessage 로 오류 상황을 나타내는 정도로도 충분히 표현이 가능하다면, 굳이 커스텀 예외를 사용하지 않는것이 좋다.
반대로 CustomException을 받는 곳에서 처리하기 쉽기 위해 추가로 에러에 관한 정보를 넣어주거나, 여러 타입의 Exception이 발생할 수 있는 코드에서 한가자로 Exception 타입으로 묶어 처리할때는 custome exception을 사용할만 하다.
표준 예외를 사용하면 가독성이 높아진다.
NullPointerException : null을 허용하지 않는 메서드에 null을 건냈을 때
IndexOutBoundsException : 범위 밖의 index에 접근할 때
IllegalArgumentException : 허용하지 않는 값이 인수로 건네졌을 때
IllegalStateException : 객체가 메서드를 수행하기에 적절하지 않은 상태일 때
UnsupportedOperationException : 요청받은 작업을 지원하지 않는 경우 일 때
HandlerExceptionResolver
이렇게 모든 코드에 try-catch를 사용하는 것은 비효율적이다.
스프링은 예외처리를 추상화한 HandlerExceptionResolver
인터페이스를 만들었다. (에러 처리를 메인 로직으로 부터 분리)
public interface HandlerExceptionResolver {
ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex);
}
@ResponseStatus
에러 HTTP 상태를 변경
// ex. 특정 예외에 대해 404 Not Found 상태 코드를 반환하고자 할 때
@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
// 예외 클래스 내용...
}
참조
https://adjh54.tistory.com/79 [Contributor9:티스토리]