티스토리 뷰

Exception 처리 방법 

1. @ExceptionHandler + @RestControllerAdvice 

  • 전역 Exception 처리를 지원한다
  • ResponseEntity를 사용하여 예외를 처리할 수 있다
  • 같은 메소드에 여러 Exception을 매핑하여 사용이 가능하다 
@ControllerAdvice
@RestController
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<?> processValidationError(MethodArgumentNotValidException exception) {
        BindingResult bindingResult = exception.getBindingResult();
        StringBuilder builder = new StringBuilder();
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            builder.append("{");
            builder.append("error field: "+fieldError.getField());
            builder.append(" message: "+fieldError.getDefaultMessage());
            builder.append(" value: "+fieldError.getRejectedValue());
            builder.append("}, ");
        }

        String errors = builder.toString();

        BaseResponse baseResponse = new BaseResponse(400, errors, "0001", "요청값이 잘못되었습니다.");

        return ResponseEntity.ok().body(baseResponse);
    	}
    }
  • MethodArgumentNotValidException : @valid를 통한 dto 필드 검증시 발생하는 예외를 처리해주는 클래스
  • BaseResponse : 개발자가 정의한 ErrorResponse  객체 
  • ResponseEntity를 사용하여 리턴

2. ResponseStatusException (Spring 5 이상)

  • 전역 Exception 처리를 지원한다
  • HttpStatus를 제공하고 이유&원인을 제공하는 인스턴스를 만들어 사용이 가능하다
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ResponseStatusException;

public class ForbiddenException extends ResponseStatusException {
    public ForbiddenException(String message) {
        super(HttpStatus.FORBIDDEN,message);
    }
}
public class PasswordMismatchException extends ForbiddenException {
    public PasswordMismatchException(){super("Password is wrong");}
}
  • @ExceptionHadler를 사용할 필요 없이 바로 예외를 던질 수 있다 

깔끔한 Exception 처리 전략 

1. ErrorCode 정의

비즈니스단의 예외를 처리하는 경우에는 ErrorCode를 Enum으로 정의하고 BuisnessException을 사용하여 @ExceptionHandler에서 통일성 있게 처리하는 것이 바람직하다. 

public enum ErrorCode {

    // Common
    INVALID_INPUT_VALUE(400, "C001", " Invalid Input Value"),
    METHOD_NOT_ALLOWED(405, "C002", " Invalid Input Value"),
    ....
    HANDLE_ACCESS_DENIED(403, "C006", "Access is Denied"),

    // Member
    EMAIL_DUPLICATION(400, "M001", "Email is Duplication"),
    LOGIN_INPUT_INVALID(400, "M002", "Login input is invalid"),

    ;
    private final String code;
    private final String message;
    private int status;

    ErrorCode(final int status, final String code, final String message) {
        this.status = status;
        this.message = message;
        this.code = code;
    }
}
@Getter
public class BusinessLogicException extends BusinessException {
    private ErrorCodeType errorCodeType;

    public BusinessLogicException(ErrorCodeType errorCodeType) {
        super(errorCodeType.getMessage());
        this.errorCodeType = errorCodeType;
    }
}
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(BuisnisLogicException.class)
    public ResponseEntity handleNotFoundException(BuisnisLogicException e) {
    	ErrorCodeType errorCodeType = e.getErrorCodeType();
        String message = errorCodeType.getMessage();
        Integer status = errorCodeType.getStatus();
        String code = errorCodeType.getCode();
        BaseResponse baseResponse = new BaseResponse(status, "errors", code, message);

        return ResponseEntity.ok().body(baseResponse);
    }
    }
  • ErrorType 으로 비즈니스단의 에러코드를 정의
  • 정의한 에러코드를 BusinessLogicException 클래스에 적용하여 사용
    • ExceptionHandler로 BsinessLoginException을 실행시키고 적절한 ErrorResponse 객체를 생성하여 반환

2. 통일된 ErrorResponse 객체 사용 

통일된 ErrorResponse를 사용하므로써 클라이언트에서 예외처리를 항상 동일한 로직으로 처리할 수 있도록한다

@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class BaseResponse {
    private Integer status = 200;
    private String errors = "";
    private String errorCode = "";
    private String errorMessage = "";
}

 

참고 블로그

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함