[Spring] @ExceptionHandler를 통한 controller 계층 예외처리

sunny·2023년 7월 19일
0

ExceptionHandler란?
@ExceptionHandler 는 Controller 계층에서 발생하는 에러를 잡아서 메서드로 처리해주는 기능을 제공한다.

MethodArgumentNotValidException

@Valid Annotation이 달린 인수에 대한 유효성 검사가 실패할 때 발생하는 예외

주로 Request Body의 인수 유효성 검사를 할 때 사용한다!

1. MethodArgumentNotValidException ExceptionHandler 추가

@RestControllerAdvice
@Component
@RequiredArgsConstructor
public class ControllerExceptionAdvice {

	@ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    protected ApiResponse handleMethodArgumentNotValidException(final MethodArgumentNotValidException e) {
        FieldError fieldError = Objects.requireNonNull(e.getFieldError());
        return ApiResponse.error(Error.VALIDATION_REQUEST_MISSING_EXCEPTION, String.format("%s. (%s)", fieldError.getDefaultMessage(), fieldError.getField()));
    }

}

2. 검증할 필드에 Annotation 추가

// GoalRequestCreateDto.java

@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class GoalRequestCreateDto {

    @DecimalMin(value = "30000") // 조건 : 30,000 이상
    private Long targetMoney;

    @DecimalMin(value = "5") // 조건 : 5 이상
    private int targetDay;
}

3. Controller에 @Valid Annotation 추가

// GoalController.java

@RestController
@RequiredArgsConstructor
@RequestMapping("/goal")
public class GoalController {

    private final GoalService goalService;

    @PostMapping("")
    @ResponseStatus(HttpStatus.CREATED)
    public ApiResponse<GoalResponseCreateDto> create(@RequestBody @Valid final GoalRequestCreateDto requestDto, @RequestHeader Long userId) {
        return ApiResponse.success(Success.CREATE_GOAL_SUCCESS, goalService.createGoal(requestDto, userId));
    }
}

MissingRequestHeaderException

@RequestMapping 메서드의 메서드 매개 변수에 예상되는 요청 헤더가 없을 때발생하는 예외

Request Header 값 유무를 검사할 때 사용한다!

MissingRequestHeaderException ExceptionHandler 추가

@RestControllerAdvice
@Component
@RequiredArgsConstructor
public class ControllerExceptionAdvice {

	@ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MissingRequestHeaderException.class)
    protected ApiResponse handleMissingRequestHeaderException(final MissingRequestHeaderException e) {
        return ApiResponse.error(Error.VALIDATION_REQUEST_HEADER_MISSING_EXCEPTION, String.format("%s. (%s)", Error.VALIDATION_REQUEST_HEADER_MISSING_EXCEPTION.getMessage(), e.getHeaderName()));
    }

}

MissingServletRequestParameterException

파라미터가 누락되었을 때 발생하는 예외

MissingServletRequestParameterException ExceptionHandler 추가

@RestControllerAdvice
@Component
@RequiredArgsConstructor
public class ControllerExceptionAdvice {

		@ResponseStatus(HttpStatus.BAD_REQUEST)
		@ExceptionHandler(MissingServletRequestParameterException.class)
		protected ApiResponse handleMissingRequestParameterException(final MissingServletRequestParameterException e) {
		    return ApiResponse.error(Error.VALIDATION_REQUEST_PARAMETER_MISSING_EXCEPTION, String.format("%s. (%s)", Error.VALIDATION_REQUEST_PARAMETER_MISSING_EXCEPTION.getMessage(), e.getParameterName()));
		}

}

HttpRequestMethodNotSupportedException

Request Handler가 특정 요청 메서드를 지원하지 않을 때 발생하는 예외

👉 Request method ‘POST’ not supported 오류

HttpRequestMethodNotSupportedException ExceptionHandler 추가

@RestControllerAdvice
@Component
@RequiredArgsConstructor
public class ControllerExceptionAdvice {

		@ResponseStatus(HttpStatus.BAD_REQUEST)
		@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
		protected ApiResponse handleHttpRequestMethodNotSupportedException(final HttpRequestMethodNotSupportedException e) {
		    return ApiResponse.error(Error.REQUEST_METHOD_VALIDATION_EXCEPTION, e.getMessage());
		}

}

1개의 댓글

comment-user-thumbnail
2023년 7월 19일

이 글을 읽고 많이 배웠습니다.

답글 달기