Language/Java

[Java] ExceptionHandler를 이용한 에러 처리

별토끼. 2021. 8. 6. 23:59
반응형

에러가 발생하면 클라이언트에 error message를 전달한다. 좀 더 상세하게 전달하고 싶어 반복적으로 예외를 처리를 했는데 코드가 너무 지저분해 보였다. 이럴 때, ExceptionHandler가 굉장히 유용하다. 예외처리를 좀 더 잘해볼 수 있는 방법을 공부해보자 !

Intro

예외 처리는 굉장히 중요하지만, 놓치는 부분이 많고 어렵다. 주로 사용하는 방식은 try-catch 방식인데 비즈니스 로직에 너무 많이 들어가게 되면 코드가 아주 지저분해지고 복잡해진다.

파라미터를 잘못 전달(400 Error)하거나 알 수 없는 에러(500 Error)가 발생하는 경우는 이걸 하나 하나 다 처리를 하려니 너무 번거로웠고 지저분했다.

이때, ExceptionHandler를 이용하면 비즈니스 로직에 집중할 수 있도록 개선할 수 있다.

@ExceptionHandler

@ExceptionHandler는 @Controller, @RestController가 적용된 Bean 내에서 발생하는 예외를 잡아 하나의 메서드에서 처리해주는 기능이다.

동작 방식

@RestController 혹은 @Controller에서 예외 발생 시, Srping은 @ExceptionHandler를 검색하여 특정 메서드가 처리할 수 있도록 수행한다.

@RestController
public class ExceptionController {

    @GetMapping("/userInfo")
    public User getUserInfo(@RequestParam Long id) {
        if (id < 1L) {
            throw new UserException("{} 는 존재하지 않는 user id 입니다.",id);
        }
        return new User("tokki","kim");
    }

    @ExceptionHandler({UserNotFoundException.class,NullPointerException.class})
    public Map<String, String> handle(UserNotFoundException e) {
        log.error(e.getMessage(), e);
        Map<String, String> errorAttributes = new HashMap<>();
        errorAttributes.put("errorCode", "USER_NOT_FOUND");
        errorAttributes.put("errorMessage", e.getMessage());
        return errorAttribute;
    }
}

결과는 아래와 같다.

{
    "errorCode" : "USER_NOT_FOUND",
    "errorMessage" : "HEE 는 존재하지 않는 user id 입니다."
}

이것은 알고 쓰자

  • @RestController, @Controller 에만 적용할 수 있다.
  • try-catch를 통해 직접 예외 처리를 하면 우선 순위가 밀린다.
  • 리턴 타입은 보통의 핸들러와 마찬가지로 @ResponseStatus를 통해 응답 코드를 정의하거나, ModelAndView, String, ResponseEntity 등을 사용할 수 있다.
  • 에러 메시지로 나가는 포맷이 일정해야 한다.
    • 예를 들어, 여러 서비스의 에러 타입을 통합하려 한다. @ControllerAdvice를 이용해 통합하려 하지만, 리턴 타입이 다르면 통합 처리가 불가능하다.

참고
https://supawer0728.github.io/2019/04/04/spring-error-handling/
https://velog.io/@hanblueblue/Spring-ExceptionHandler
https://jeong-pro.tistory.com/195

반응형