Projects/Problem & Solution

Sneakers Mania - @ControllerAdvice, @ExceptionHandler를 이용한 전역 예외 처리

임빈영 2022. 1. 3. 13:42

개요

문제점

존재하지 않는 게시물을 조회하거나 존재하지 않는 게시물을 수정하는 등 예기치 못한 상황에서 발생하는 예외들을 전역적으로 처리할 필요가 있었다.

기존에는 각 비즈니스 로직을 담당하는 메서드 내 try-catch 문을 사용해서 예외처리를 하였으나, 이런 방식으로 예외처리를 하면 프로그램이 커지고 기능이 추가됨에 따라 유지보수가 어렵고, 코드가 복잡해지겠다고 생각하였다.

이러한 문제를 개선시키고자 전역적으로 예외를 관리할 수 있는 방법을 모색하였다.

 

해결 방안

 

애너테이션 설명
@ControllerAdvice 모든 Controller에서 발생할 수 있는 Exception을 전역으로 처리하기 위해 사용
@ExceptionHandler 컨트롤러 내 특정 Exception을 처리하기 위한 애너테이션

"@ControllerAdvice", "@ExceptionHandler" 애너테이션을 사용함으로써 위 문제를 개선할 수 있었다.


구현 방법

1. ResponseDto 클래스 생성
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ResponseDto<T> {
    int status;

    T data;
}

예외가 발생했을 때 클라이언트에게 전달할 에러 메시지이다.

메시지는 JSON 형태로 전달된다.

 

2. GlobalExceptionHandler 클래스 생성
@ControllerAdvice
@RestController
public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    public ResponseDto<String> handleArgumentException(Exception e) {
        return new ResponseDto<String>(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }
}

전역으로 예외를 처리하는 클래스인 GlobalExceptionHandler 클래스를 생성한다.

클래스 범위에 "@ControllerAdvice" 애너테이션을 선언하며, 해당 애너테이션을 선언한 클래스는 추후 생기는 Exception을 낚아채서 처리한다.

클래스 내에 특정 Exception을 처리하기 위한 메서드인 handleArgumentException() 메서드를 생성하고, "@ExceptionHandler" 애너테이션을 선언한다.

"@ExceptionHandler" 애너테이션 내의 (value = Exception.class)의 의미는 Exception이 발생했을 때, 해당 메서드를 호출하겠다는 의미이다.

이 외에도 (value = IllegalArgumentException.class) 등의 설정이 가능하다.


테스트

1. 예외 상황

 

위 사진은 특정 id의 게시물을 조회하려고 했을 때, 해당 게시물이 존재하지 않을 경우 발생하는 예외이다.

즉, 조회하려는 게시물이 데이터베이스 내 없을 경우 "해당 게시글을 찾을 수 없습니다."라는 예외를 발생한다.

 

2. 존재하지 않는 게시물 조회

 

id가 20번인 게시물(존재하지 않는 게시물)을 조회했을 때의 상황이다.

존재하지 않는 게시물을 조회할 경우 예외를 발생하며, 예외가 발생했을 때, GlobalExceptionHandler 클래스 내의 handleArgumentException() 메서드가 해당 예외를 가로채서 클라이언트에게 JSON 형태로 전달하는 것을 확인할 수 있다.


 

GitHub - qlsdud0604/sneakers-mania: 👟 신발 사진을 업로드하고 소통할 수 있는 커뮤니티

👟 신발 사진을 업로드하고 소통할 수 있는 커뮤니티. Contribute to qlsdud0604/sneakers-mania development by creating an account on GitHub.

github.com

 

728x90