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에서만 처리하도록 하니까 정말 편하고 좋았다. ᜊʕ ྀི ܸ...ܸ ྀིʔᜊ
위의 결과처럼 내가 원하는 형식으로만 반환이 되었다!