예외처리는 안정적인 프로그램을 만드는 데에 매우 중요한 작업이다.
이번에는 이 예외 처리를 도와주는 스프링 어노테이션에 대해 간략히 알아보려고 한다.
@ExceptionHandler
Handler는 '자동으로 호출되는 메소드'를 뜻한다.
따라서 ExceptionHandler는 '예외가 발생하면 자동으로 호출되는 메소드'를 말한다.
앞서 예외 처리를 어디에서 해줄 것인가와 관련한 글을 올렸다.
오늘 알게된 사실..! 예외 처리는 최대한 미루면 좋다!
왜 그럴까?
Spring에서는 컨트롤러에 모인 예외를 한 번에 처리해줄 수 있기 때문에 최대한 미뤄서 컨트롤러에 예외를 모아놓고 한 번에 처리하면 편하고 좋다!
Controller에서 @ExceptionHandler를 써서 예외처리를 해줄 수 있다.
@RestController
public class HotelController {
private final HotelService hotelService;
@Autowired
public HotelController(HotelService hotelService) {
this.hotelService = hotelService;
}
@RequestMapping(value = "/hotels/{id}", method = RequestMethod.GET)
public ResponseEntity<HotelDetailResponse> getHotel(@PathVariable int id) {
return new ResponseEntity<>(hotelService.getHotel(id), HttpStatus.OK);
}
@ExceptionHandler(value = HotelNotFoundException.class)
public ResponseEntity<String> catchHotelNotFoundException() {
return new ResponseEntity<>("그런 호텔 없으세요;;", HttpStatus.NOT_FOUND);
}
}
getHotel에서 HotelNotFoundException 에러가 뜨면, @ExceptionHandler가 그 에러를 잡고 어노테이션 바로 아래 메소드를 실행시킨다.
❗️RoomController 클래스에 있는 @ExceptionHandler를 HotelController에서 사용할 수 있을까?
답은 "안된다!"이다.
여기서 우리는 하나의 문제에 직면한다.
RoomController와 HotelController에서 같은 예외가 터진다면 각 컨트롤러 클래스에 똑같은 @ExceptionHandler 메소드를 만들어야 한다.
즉, 중복 코드가 우후죽순 생겨날 수 있다.
이는 클린코드가 아닐 것이다. 그렇다면 우리는 공통 Exception 처리 클래스를 만들어서 한 곳에서 처리하자는 결론을 얻을 수 있다!
@ControllerAdvice
@ControllerAdvice를 붙여서 공통 클래스를 만들면 모든 Controller들의 공통 Exception 처리 클래스 생성이 가능하다!
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(HotelNotFoundException.class)
public ResponseEntity<String> handleHotelNotFoundException() {
return new ResponseEntity<>("그런 호텔 없으세요", HttpStatus.NOT_FOUND);
}
}
위와 같은 공통 Exception 처리 클래스를 만들고 기존 HotelController에 있던 @ExceptionHandler 메소드를 지우면 GlobalExceptionHandler가 예외를 잡아서 처리해준다.
'백엔드 > Spring' 카테고리의 다른 글
| 공통 작업을 처리해주는 AOP (0) | 2024.07.31 |
|---|---|
| Entity와 영속화 (2) | 2024.07.29 |
| 예외 처리 위치에 대한 고민 (2) | 2024.07.24 |
| DTO에 대해 (1) | 2024.07.22 |
| 직렬화 vs 역직렬화 (1) | 2024.07.19 |