본문 바로가기

Develop/Spring

Spring Exception

728x90

예외?

프로그램이 예상치 못한 상황을 만났을 때 오류를 발생시키는 것 입니다. throw new Exception()

 

일반적인 자바 프로그램이 예외를 처리하는 방법

try {
    doSomething();
} catch (Exception e) {
    log.error("Exception is occured", e);
    handleException(e);
    // throw e;
}

스프링 MVC에서 예외를 처리하는 방법 (REST API용)

@ExceptionHandler

  • 컨트롤러 기반 예외 처리
  • HTTP Status code를 변경하는 방법
    1. @ResponseStatus
    2. ResponseEntity 활용
  • 예외처리 우선순위
    1. 해당 Exception이 정확히 지정된 Handler
    2. 해당 Exception의 부모 예외 Handler
    3. 이도 저도 아니면 그냥 Exception(모든 예외의 부모)

@ResponseStatus를 사용한 컨트롤러 기반 예외 처리

@ResponseStatus(HttpStatus.FORBIDDEN)
@ExceptionHandler(IllegalAccessException.class)
public ErrorResponse handleIllegalAccessException(
        IllegalAccessException e) {
    log.error("IllegalAccessException is occured.", e);
    return new ErrorResponse("INVALID_ACCESS",
            "IllegalAccessException is occured.");
}

@AllArgsConstructor
@Data
public static class ErrorResponse {
    private String errorCode;
    private String message;
}

ResponseEntity를 사용한 컨트롤러 기반 예외 처리

@ExceptionHandler(IllegalAccessException.class)
public ResponseEntity<ErrorResponse> handleIllegalAccessException(
        IllegalAccessException e) {
    log.error("IllegalAccessException is occured.", e);
    return ResponseEntity
            .status(HttpStatus.FORBIDDEN)
            .body(new ErrorResponse(ErrorCode.TOO_BIG_ID_ERROR,
                    "IllegalAccessException is occuered."));
}

예외처리 우선순위

마지막으로 Exception을 핸들링하는 부분을 두어서 ErrorCode를 원하는 형태로 정제하는 것이 중요합니다.

@ExceptionHandler(IllegalAccessException.class)
public ResponseEntity<ErrorResponse> handleIllegalAccessException(
        IllegalAccessException e) {
    log.error("IllegalAccessException is occured.", e);
    return ResponseEntity
            .status(HttpStatus.FORBIDDEN)
            .body(new ErrorResponse(ErrorCode.TOO_BIG_ID_ERROR,
                    "IllegalAccessException is occuered."));
}

@ExceptionHandler(WebSampleException.class)
public ResponseEntity<ErrorResponse> handleWebSampleException(
        WebSampleException e) {
    log.error("WebSampleException is occured.", e);
    return ResponseEntity
            .status(HttpStatus.INSUFFICIENT_STORAGE)
            .body(new ErrorResponse(e.getErrorCode(),
                    "WebSampleException is occured."));
}

@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleException(
        Exception e) {
    log.error("Exception is occured.", e);
    return ResponseEntity
            .status(HttpStatus.INTERNAL_SERVER_ERROR)
            .body(new ErrorResponse(ErrorCode.INTERNAL_SERVER_ERROR,
                    "Exception is occured."));
}

@RestControllerAdvice

컨트롤러 하나가 아니라 애플리케이션의 전역적인 예외처리에 사용됩니다.

 

@ControllerAdvice랑의 차이는?

  • Controller vs RestController의 차이와 동일합니다.
  • ControllerAdvice는 기본적으로 view를 응답하는 방식입니다.
  • RestControllerAdvice는 REST API용으로 객체를 응답하는 방식입니다.

스프링 백엔드 개발에서 현재 가장 많이 활용되는 기술입니다. (일관적인 예외 및 응답 처리)

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    
    @ResponseStatus(value = HttpStatus.FORBIDDEN)
    @ExceptionHandler(IllegalAccessException.class)
    public ErrorResponse handleIllegalAccessException(IllegalAccessException e) {
        log.error("Illegal Exception : ", e);
        return new ErrorResponse("ACCESS_DENIED", "Illegal Exception occured.");
        }
    }
}

'Develop > Spring' 카테고리의 다른 글

Spring Boot ServletInitializer  (0) 2022.12.15
Spring Test (JUnit, Mockito, Spring Boot)  (0) 2022.11.21
Spring Filter, Interceptor  (0) 2022.11.17
Spring MVC  (0) 2022.11.17
(작성 중) Spring web.xml  (0) 2022.11.16