[Spring] Global Exception with @Order

HOJUN·2024년 6월 6일

Backend - Spring

목록 보기
9/34

Global Exception

하나의 Exception Handler에서 Exception 클래스를 Handling하는 경우
Global Controller의 예외처리가 부족할 수 있다.

주로 한 비즈니스 로직에서 발생하는 ErrorCode는 Enum Class로 분류해놓는 경우가 많은데,
공통 모듈에서는 각 서비스 모듈의 구현에 영향받지 않고 Internal하게 작동하도록 할 수 있다.

모든 모듈에서 어떠한 예외가 발생하더라도 동일한 response를 내주는 서버가 되기 위해서 default handler가 필요하다

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = {Exception.class})
    public ResponseEntity<Api> exception(
            Exception e
    ){
        log.error("", e);
        var response = Api.builder()
                .resultCode(String.valueOf(HttpStatus.INTERNAL_SERVER_ERROR.value()))
                .resultMessage(HttpStatus.INTERNAL_SERVER_ERROR.name())
                .build();

        return ResponseEntity
                .status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(response);
    }
}

바로 Global Handler를 만들어주는 것이다.
물론 이 Handler에서 처리하는 예외는 서버에서 예측하지 못한 예외를 처리하는 것으로
500 ERROR를 내리도록 한다.

specific한 error를 처리하는 handler는 물론 가장 먼저 처리해야한다.

@Order는 예외처리만이 아니라 어떤 Bean이 먼저 수행되고 어떤 순서로 처리되는지 정할 수 있다.

@Slf4j
@RestControllerAdvice(basePackageClasses = {RestApiController.class})
@Order(1)
public class RestApiExceptionHandler {

    @ExceptionHandler(value = {Exception.class})
    public ResponseEntity<Api> exception(
            Exception e
    ) {
        log.error("", e);
        var response = Api.builder()
                .resultCode(String.valueOf(HttpStatus.INTERNAL_SERVER_ERROR.value()))
                .resultMessage(HttpStatus.INTERNAL_SERVER_ERROR.name())
                .build();

        return ResponseEntity
                .status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(response);
    }

@Order(1)은 가장 먼저 우선적으로 동작하도록 한다.

500 ERROR를 발생시키고 실제 서버 로그를 확인해보면

같은 RuntimeException을 처리하지만 우선순위가 높은 Handler가 처리한 것을 볼 수 있다.

0개의 댓글