본문 바로가기
Spring Boot

Spring Boot - Exception 구현 예제2

by sinabeuro 2021. 11. 29.
728x90

Exception 객체에서 getBindingResult() 메소드를 사용해서 

BindingResult 데이터를 추출해서 에러 객체(ErrorResponse)를 만들어 준 점이 유용하다고 생각하여 기록용으로 글을 남깁니다.

에러가 복수건 이거나 에러 필드가 여러개 일 때 BindingResult를 이용해서 복수 에러 처리를 하면 될 것 같습니다.

@ControllerAdvice
@ResponseBody
@Slf4j
public class GlobalExceptionAdvice {

  @ExceptionHandler(Exception.class)
  @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
  protected ErrorResponse handleInternalServerError(Exception e) {
    log.error("{}: {}", HttpStatus.INTERNAL_SERVER_ERROR, e);
    return buildError(ErrorCode.INTERNAL_SERVER_ERROR, e);
  }

  @ExceptionHandler(MethodArgumentNotValidException.class)
  @ResponseStatus(HttpStatus.BAD_REQUEST)
  protected ErrorResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
    log.error("{}: {}", HttpStatus.BAD_REQUEST, e);
    final List<ErrorResponse.FieldError> fieldErrors = getFieldErrors(e.getBindingResult());
    return buildFieldErrors(ErrorCode.INTERNAL_SERVER_ERROR, fieldErrors);
  }

  private List<ErrorResponse.FieldError> getFieldErrors(BindingResult bindingResult) {
    final List<FieldError> errors = bindingResult.getFieldErrors();
    return errors.parallelStream()
            .map(error -> ErrorResponse.FieldError.builder()
                    .reason(error.getDefaultMessage())
                    .field(error.getField())
                    .value((String) error.getRejectedValue())
                    .build())
            .collect(Collectors.toList());
  }

  private ErrorResponse buildError(ErrorCode errorCode, Exception e) {
    return ErrorResponse.builder()
            .code(errorCode.getCode())
            .status(errorCode.getStatus())
            .message(errorCode.getMessage())
            .build();
  }

  private ErrorResponse buildFieldErrors(ErrorCode errorCode, List<ErrorResponse.FieldError> errors) {
    return ErrorResponse.builder()
            .code(errorCode.getCode())
            .status(errorCode.getStatus())
            .message(errorCode.getMessage())
            .errors(errors)
            .build();
  }
}

 

 

아래는 ErrorResponse 클래스입니다.

참고 하시면 좋을것 같습니다.

@Getter
public class ErrorResponse {

  private String message;
  private String code;
  private int status;
  private List<FieldError> errors;

  @Builder
  public ErrorResponse(String message, String code, int status, List<FieldError> errors) {
    this.message = message;
    this.code = code;
    this.status = status;
    this.errors = initErrors(errors);
  }

  private List<FieldError> initErrors(List<FieldError> errors) {
    return (errors == null) ? new ArrayList<>() : errors;
  }

  @Getter
  public static class FieldError {
    private String field;
    private String value;
    private String reason;

    @Builder
    public FieldError(String field, String value, String reason) {
      this.field = field;
      this.value = value;
      this.reason = reason;
    }
  }

}

 

 

@Getter
public enum ErrorCode {
  DATA_NOT_FOUND("ER_0001", "데이터를 찾을수 없습니다.", HttpServletResponse.SC_BAD_REQUEST),
  NO_CHANGE_DATA("ER_0002", "수정된 데이터가 없습니다.", HttpServletResponse.SC_INTERNAL_SERVER_ERROR),
  BAD_REQUEST("ER_0003", "잘못된 요청입니다.", HttpServletResponse.SC_BAD_REQUEST),
  INTERNAL_SERVER_ERROR("ER_9999", "오류가 발생 했습니다.", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  
  private final String code;
  private final String message;
  private final int status;

  ErrorCode(String code, String message, int status) {
    this.code = code;
    this.message = message;
    this.status = status;
  }

}
728x90

'Spring Boot' 카테고리의 다른 글

Spring Boot - 정적 파일 경로 지정  (0) 2021.11.05
Spring Boot - Swagger  (0) 2021.10.01
Spring Boot - 서버 간 통신 예제  (0) 2021.09.26
Spring Boot - 서버 간 통신 RestTemplate 정의  (0) 2021.09.25
Spring Boot - Interceptor  (0) 2021.09.23

댓글