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 |
댓글