Spring

[Spring] @ExceptionHandler를 통한 예외 처리 (+ DTO Validation)

DAHLIA CHOI 2024. 3. 5. 17:22

 

 

프로젝트를 진행하다가 예외를 처리해야 하는 경우가 생겼다! 

해당 예외에 대한 결과 값도 반환했어야 해서 try-catch를 사용할까 했지만 반환형 식이 달라서 어떻게 처리를 해야 할까 고민을 하던 중에 @ExceptionHandler를 통해서 처리해 주기로 결정했다!

 

근데 @ExceptionHandler를 사용하려는 컨트롤러에 매번 지정을 해주게 되면 코드 중복이 너무 많이 발생하게 돼서 @ControllerAdvice를 통해 전역적으로 예외를 핸들링 할 수 있게 처리했다.

 

 

🔎 사용한 코드

@RestControllerAdvice
public class ExceptionAdviceController {

    private final ResponseService responseService;

    public ExceptionAdviceController(ResponseService responseService) {
        this.responseService = responseService;
    }

    /**
     * CommonConflictException 처리
     * @param e
     * @return commonResult
     */
    @ResponseStatus(HttpStatus.CONFLICT)
    @ExceptionHandler(CommonConflictException.class)
    public CommonResult conflictException(CommonConflictException e) {
        return responseService.getFailResult(e.getMessage());
    }

    /**
     * MethodArgumentNotValidException 처리 (DTO validation)
     * @param e
     * @return List<CommonResult>
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public List<CommonResult> methodArgumentNotValidException(MethodArgumentNotValidException e) {

        List<CommonResult> errors = new ArrayList<>();
        e.getBindingResult().getAllErrors().forEach((error)-> {
            String exception = error.getDefaultMessage();
            errors.add(responseService.getFailResult(exception));
        });

        return errors;
    }

}

 

 

나 같은 경우는 해당 예외를 각각 다른 클래스로 만들어서 예외처리를 하도록 했다.

 

 

@ResponseStatus(HttpStatus.CONFLICT)
@ResponseStatus는 Http 상태코드를 지정시켜준다. 

 

상태코드는 너무 많기 때문에 내가 자주 사용한 것만 몇개 적어보자면

  • HttpStatus.CONFLICT
  • HttpStatus.BAD_REQUEST
  • HttpStatus.INTERNAL_SERVER_ERROR 

 

서비스 로직에서 발생한 예외뿐만 아니라 DTO를 통한 Validation에도 적용이 된다는 것을 알고 완전 유레카를 외쳤던...

 

기존에 서비스 리펙토링을 하기 전에는 컨트롤러에서 일일히 정보를 불러오고 해당 예외에 대한 것을 switch ~ case로 정의해서 처리했었는데 비즈니스 로직에서의 추가적인 코드 없이 단지 Controller Advice에서만 처리하도록 하니까 정말 편하고 좋았다. ᜊʕ ྀི ܸ...ܸ ྀིʔᜊ

 

 

 

위의 결과처럼 내가 원하는 형식으로만 반환이 되었다!