에러 핸들링에 대해서 공부하는 와중에 정말로 이해하고 쉬운 예시를 보여주는 블로그를 찾았다.
이론 정리도 할 겸 해당 블로그 주소와 함께 예시를 가져와 봤음.
스프링 공식 문서를 정리한 것이라고 한다.
[스프링부트] @ExceptionHandler를 통한 예외처리
@ExceptionHandler는 Controller계층에서 발생하는 에러를 잡아서 메서드로 처리해주는 기능이다.Service, Repository에서 발생하는 에러는 제외한다.간단한 예시부터 살펴보자.이렇게 @Controller로 선언된 클
velog.io
큰 틀에서 보자면 기존 방식 >> 새로운 방식으로 전환하는 방향으로 예시가 적혀있다.
컨트롤러 내부에서 발생한 에러를 컨트롤러에서 매번 처리하기 보다는, 예외 처리 클래스를 구성해서 처리하는 방식이다.
리팩토링 순서를 이렇게 된다.
- 에러 발생 시 보낼 정보를 담는 DTO를 생성
- 에러 코드를 처리할 ENUM 클래스를 생성
- 에러를 담당할 개별 예외 처리 클래스를 생성
- 전역적으로 예외 처리를 담당할 전역 예외 처리 클래스를 생성하여 개별 예외 처리 클래스를 주입
1. DTO
글에는 적혀 있지 않지만 이런 방식일 것이라고 추측했다.
@AllArgsConstructor
@Getter
@Setter
public class ErrorDto {
private int status;
private String message;
}
2. Enum
일단 Enum 클래스에는 @Setter를 안 붙여주는 것도 인상적이다. 확실히 외부에서 변경할 이유가 없긴 하다.
눈여겨 봐야할 점은 404 에러는 다양한 경우의 수를 상정했다는 점이다.
@AllArgsConstructor
@Getter
public enum ErrorCode {
//400 BAD_REQUEST 잘못된 요청
INVALID_PARAMETER(400, "파라미터 값을 확인해주세요."),
//404 NOT_FOUND 잘못된 리소스 접근
DISPLAY_NOT_FOUND(404, "존재하지 않는 전시회 ID 입니다."),
FAIR_NOT_FOUND(404, "존재하지 않는 박람회 ID 박람회입니다."),
FESTIVAL_NOT_FOUND(404, "존재하지 않는 페스티벌 ID 페스티벌입니다."),
// ... write something
private final int status;
private final String message;
}
3. CustomException Class
해당 클래스는 위처럼 404 에러를 다양한 경우로 잡을 경우 필요한 클래스다.
기본 제공되는 404 에러 외에도 이것이 정의된 에러라는 것을 알려야 하기 때문인 듯하다.
전역 예외 처리 클래스에서는 이 클래스를 사용한다.
@AllArgsConstructor
@Getter
public class CustomException extends RuntimeException {
private final ErrorCode errorCode;
}
4. Global Exception Class
에러 발생 시 반환할 값으로 에러 코드(status), 에러 내용(message), 처리 결과(httpStatus) 세 개가 설정됐다.
HttpStatus는 별도로 String 타입으로 치환했던데 이 부분을 인지해야겠다.
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler({ CustomException.class })
protected ResponseEntity handleCustomException(CustomException ex) {
return new ResponseEntity(new ErrorDto(ex.getErrorCode().getStatus(), ex.getErrorCode().getMessage()), HttpStatus.valueOf(ex.getErrorCode().getStatus()));
}
@ExceptionHandler({ Exception.class })
protected ResponseEntity handleServerException(Exception ex) {
return new ResponseEntity(new ErrorDto(INTERNAL_SERVER_ERROR.getStatus(), INTERNAL_SERVER_ERROR.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
'Back > Spring' 카테고리의 다른 글
DTO에 무엇을 담아야 적절할까? (0) | 2023.02.08 |
---|---|
Spring framework는 기본적으로 String 타입을 사용한다 (0) | 2023.02.01 |
서비스 디스커버리, 서비스 레지스트리 패턴이란? (0) | 2023.01.22 |
[Spring] MediaType에 text/plain; utf=8;은 어떻게 적용할까? (0) | 2022.11.01 |