하나의 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가 처리한 것을 볼 수 있다.