본문 바로가기
개념서/Spring

[Spring] @ExceptionHandler

by 사서T 2023. 1. 31.

@ExceptionHandler란?

@ExceptionHandler는 컨트롤러 메서드의 예외를 처리하기위한 애노테이션으로 예외처리시 수행할 메서드에 선언한다. 컨트롤러 메서드에서 발생한 예외가 @ExceptionHandler에 선언된 예외인 경우 해당 메서드를 수행한다. @Controller, @CotrollerAdvice, @RestController, @RestControllerAdvice가 선언된 클래스에서 사용된다.

 

@Controller
public class SimpleController {

    // ...

    @ExceptionHandler
    public ResponseEntity<String> handle(IOException ex) {
        // ...
    }
}

 

@ExceptionHandler 어떻게 사용할까?

@ExceptionHandler는 value(처리할 예외 클래스)를 설정할 수 있다. 컨트롤러 메서드에서 발생할 수 있는 예외를 value로 선언하며 복수의 예외 클래스를 선언할 수 있다. 예외를 설정하지 않은 경우 선언된 메서드의 매개변수의 예외 클래스를 default 값으로 설정한다.

 

@ExceptionHandler(처리할 예외 클래스)
public ResponseEntity<String> handle(처리할 예외 클래스) {
        // ...
}

@ExceptionHandler // = @ExceptionHandler(처리할 예외 클래스 a)
public ResponseEntity<String> handle(처리할 예외 클래스 a) {
        // ...
}

 

만약 @ExceptionHandler로 부모 예외 클래스와 자식 예외 클래스(ex RuntimeException, NoSuchElementExcetion)가 모두 설정되어있을 때 NoSuchElementExcetpion이 발생하면 어떤 메서드로 처리될까? 언제나 우선순위는 더 자세한쪽이 우위를 갖기 때문에 이 경우 @ExceptionHandler(NoSuchElementException.class)를 선언한 메서드가 수행된다.

 

//자식 예외 클래스 발생!

@ExceptionHandler(부모 예외 클래스)
public ResponseEntity<String> handle(부모 예외 클래스) {
        // ...
}

@ExceptionHandler(자식 예외 클래스)
public ResponseEntity<String> handle(자식 예외 클래스) {
        //예외 클래스가 더 자세한 해당 메서드가 수행!
        // ...
}

 

두 가지 예외 클래스의 처리 내용이 같은 경우를 생각해보자. 예외 클래스 A와 에외 클래스 B를 따로 처리하는 경우 중복된 코드가 발생하고 보기 좋지 않다. @ExceptionHandler는 이를 해결하기 위해 value를 2개 이상 설정할 수 있다. 대신 이 경우 메서드의 매개변수는 두 예외의 공통적인 부모 예외 클래스를 사용해야 한다.

 

//각각 따로 처리
@ExceptionHandler(예외 클래스 A)
public ResponseEntity<String> handle(예외 클래스 A) {
     log.error("[error message]");
     //...
}

@ExceptionHandler(예외 클래스 B)
public ResponseEntity<String> handle(예외 클래스 B) {
     log.error("[error message]");
     //...
}


//동시 처리
@ExceptionHandler({예외 클래스 A, 예외 클래스 B})
public ResponseEntity<String> handle(A,B의 부모 예외 클래스) {
     log.error("[error message]");
     //...
}

@ExceptionHandler({NoSuchElementException.class, IllegalArgumentException.class})
public ResponseEntity<String> handle(RuntimeException e) {
     log.error("[error message]");
     //...
}

 

참고자료

- 스프링 MVC2 강의

- Spring Doc

댓글