240221 TIL #327 Exception 예외 처리

김춘복·2024년 2월 20일
0

TIL : Today I Learned

목록 보기
327/543
post-custom-banner

Today I Learned

오늘도 구현 과제 대비를 위해 스프링 공부를 했다. 오늘은 예외처리에 대해 정리해보았다.


Excption

웹 어플리케이션의 에러


이미지 출처

HttpStatus

  • Status Line
    : HTTP Response 메세지의 가장 첫 줄. API 요청 결과(상태코드, 상태 텍스트)
HTTP/1.1 404 Not Found
  • Http에서 서버가 클라이언트에게 보내는 Response의 가장 첫줄에는 응답 코드가 있다.
    Response Header의 가장 윗줄에 있는 세자리 번호가 API요청 결과를 나타내는 상태코드를 의미한다.

  • HTTP 상태 코드 종류

    1xx : 조건부 응답. 요청을 받았으며 작업을 진행중.
    2xx : 성공. 서버가 요청을 제대로 처리. 200 OK(성공)
    3xx : 리다이렉션 완료. 클라이언트는 요청을 마치기 위해 추가동작(리다이렉션)을 취해야한다.
    4xx : 잘못된 요청. 클라이언트 에러. 클라이언트 Request에서 오류가 났을 때.
    400 Bad Request(요청 자체가 잘못됨) 403 Forbidden(접근금지) 404 Not Found(찾을수없음)
    5xx : 서버 에러. 서버가 유효한 요청을 수행하지 못함.

  • Spring에서는 HttpStatus를 모아둔 Enum이 있어 필요할때 사용하면 된다.
    org.springframework.http > HttpStatus

  • (참고)Header의 Content type : key-value 형태로 Response 본문의 형식을 알려준다.
    (1) 없음
    (2) Response 본문 내용이 HTML - Content type: text/html
    (3) Response 본문 내용이 JSON - Content type: application/json

예외처리

  • ResponseEntity : HTTP response object를 위한 Wrapper.
    HTTP status code / HTTP headers / HTTP body 를 담아 response로 내려줄 수 있다.

@ExceptionHandler

@ExceptionHandler({ IllegalArgumentException.class }) // Exception 할 클래스 명시
public ResponseEntity handleException(IllegalArgumentException ex) {
    RestApiException restApiException = new RestApiException();
    restApiException.setHttpStatus(HttpStatus.BAD_REQUEST);
    restApiException.setErrorMessage(ex.getMessage());
    return new ResponseEntity(
            // HTTP body
            restApiException,
            // HTTP status code
            HttpStatus.BAD_REQUEST
    );
}

위의 코드를 Controller에 넣으면 그 컨트롤러의 모든 함수에 예외처리를 적용한다(AOP 활용)

@ControllerAdvice (Global 예외처리)

위와 같이 컨트롤러마다 ExeptionHandler를 다는 것은 비효율적.

@ControllerAdvice를 통해 모든 컨트롤러의 예외처리를 통합해서 할 수 있다.
(@RestControllerAdvice = @ControllerAdvice + @ResponseBody)

@RestControllerAdvice
public class RestApiExceptionHandler {

    @ExceptionHandler(value = { IllegalArgumentException.class })
    public ResponseEntity<Object> handleApiRequestException(IllegalArgumentException ex) {
        RestApiException restApiException = new RestApiException();
        restApiException.setHttpStatus(HttpStatus.BAD_REQUEST);
        restApiException.setErrorMessage(ex.getMessage());

        return new ResponseEntity(
                restApiException,
                HttpStatus.BAD_REQUEST
        );
    }
}
  • ErrorCode를 따로 Enum으로 만들어 관리해서 쓸 수도 있다.
public enum ErrorCode {
    // 400 Bad Request
    DUPLICATED_FOLDER_NAME(HttpStatus.BAD_REQUEST, "400_1", "중복폴더명이 이미 존재합니다."),
    BELOW_MIN_MY_PRICE(HttpStatus.BAD_REQUEST, "400_2", "최저 희망가는 최소 " + MIN_MY_PRICE + " 원 이상으로 설정해 주세요."),

    // 404 Not Found
    NOT_FOUND_PRODUCT(HttpStatus.NOT_FOUND, "404_1", "해당 관심상품 아이디가 존재하지 않습니다."),
    NOT_FOUND_FOLDER(HttpStatus.NOT_FOUND, "404_2", "해당 폴더 아이디가 존재하지 않습니다."),
    ;

    private final HttpStatus httpStatus;
    private final String errorCode;
    private final String errorMessage;

    ErrorCode(HttpStatus httpStatus, String errorCode, String errorMessage) {
        this.httpStatus = httpStatus;
        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
    }
}
profile
Backend Dev / Data Engineer
post-custom-banner

0개의 댓글