ExceptionHandler

JJ·2024년 7월 25일

backEnd

목록 보기
14/16

ExceptionHandler

예외가 터지면 자동으로 호출되는 메소드, @ExceptionHandler

사용자에게 알려줘야 하는 예외 처리와 개발자끼리 전달하는 예외 처리 중 사용자에게 알려줘야 하는 예외가 더 많기 때문에 스프링에서는 controller 단에 핸들러를 둔다.

@ExceptionHandler

@RequestMapping(value = "/rooms/{id}", method = RequestMethod.GET)
  public String getRoom(@PathVariable("id") int id) {
      return roomService.getRoom(id).getType();
}

@ExceptionHandler(value = RoomNotFoundException.class)
public String catchRoomNotFoundException(RoomNotFoundException e) {
    System.out.println(e.getMessage());
    return "No Room!!!";
}
  
public Room getRoom(int id) {
//    try {
        return roomRepository.getRoom(id);
//    } catch (RoomNotFoundException e) {
//       System.out.println(e.getMessage());
//       return new NullRoom();
//    }
}

서로 다른 컨트롤러에서 같은 예외를 같은 방법으로 처리해야 한다면?
→ 다른 컨트롤러끼리는 @ExceptionHandler 공유를 할 수는 있지만 수동으로 수정해줘야 함, @ControllerAdvice를 사용해서 간편하게 공통으로 처리해준다.

@ControllerAdvice

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler
    public String catchRoomNotFoundException(RoomNotFoundException e) {
        System.out.println(e.getMessage());
        return "No Room!!!";
    }

}

[에러] @ControllerAdvice를 사용했을 시에 포스트맨에서 400에러 발생.

[해결] 컨트롤러가 RestController이기 때문에 ControllerAdvice도 RestControllerAdvice로 써줘야 한다. response body의 값이 다르기 때문에 생기는 오류. RestController의 주용도는 Json 형태로 객체 데이터를 반환하는 것이다.

status code를 같이 보내주고 싶으면? @ResponseStatus

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler
    public String catchRoomNotFoundException(RoomNotFoundException e) {
        System.out.println(e.getMessage());
        return "No Room!!!";
    }
}

logging framework

SLF4J

  • Logging 관련 다양한 라이브러리들을 하나의 통일된 방식으로 사용할 수 있는 방법을 제공한다.
  • SLF4J는 로깅 Facade이다.
  • 로깅에 대한 추상 레이어를 제공하는 것이고 Interface의 모음
  • Logger

로그 레벨

아래로 내려갈수록 중요도가 높다.

  1. trace: debug레벨보다 더 상세한 정보
  2. debug: 디버깅을 위한 정보
  3. info: 정보성 로그
  4. warn: 시스템 에러의 원인이 될 수 있는 경고성 메시지
  5. error: 요청을 처리하는 중 오류가 발생한 경우

프로젝트 환경에서 로그 레벨 지정 가능! → 예를 들어 로그 레벨을 info로 지정

@RestControllerAdvice
public class GlobalExceptionHandler {
    private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler
    public String catchRoomNotFoundException(RoomNotFoundException e) {
        logger.error("exception class: {}", e.getClass());
        return "No Room!!!";
    }

}

로깅 레벨 세팅

프로젝트 환경에서 로그 레벨 지정 가능

설정 레벨과 같거나 높은 레벨의 로그들만 찍힌다.

#로그레벨을 어디까지 띄울지
#log level setting
logging.level.root=warn

서버환경에서도 별도로 로그 레벨 지정 가능

  • 개발서버의 추천 로그 레벨: debug
  • 운영서버의 추천 로그 레벨: info

lombok

slf4j logger 사용을 간편하게 하기 위해 @slf4j 어노테이션을 제공한다.

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler
    public String catchRoomNotFoundException(RoomNotFoundException e) {
        log.error("exception class: {}", e.getClass());
        return "No Room!!!";
    }
}
profile
🎀👩🏻‍💻✨🐾🌷🦅

0개의 댓글