상태 코드와 메시지를 묶어 하나의 상수로 만들기
@Getter
@RequiredArgsConstructor
public enum ErrorCode {
PERMISSION_DENIED(HttpStatus.FORBIDDEN, "해당 요청에 대한 권한이 없습니다."),
NOT_FOUND_HUB(HttpStatus.NOT_FOUND, "허브가 존재하지 않습니다.");
private final HttpStatus status;
private final String message;
}
responseEntity의 body에 넣어줄 객체를 만든다.
@Getter
@AllArgsConstructor
public class ErrorResponse {
private HttpStatus status;
private String message;
}
예외를 세분화하여 커스텀할 경우 생성한다.
@Getter
@RequiredArgsConstructor
public class MyCustomException extends RuntimeException {
private final ErrorCode errorCode;
}
@ControllerAdvice는 전역 예외 처리를 위한 어노테이션으로, 컨트롤러에서 일어나는 예외를 GlobalExceptionHandler로 잡아준다.
@RestControllerAdvice //각 메서드마다 @ResponseBody가 붙어 응답을 json으로 처리해줌
public class GlobalExceptionHandler {
@ExceptionHandler(MyCustomException.class) //특정 예외를 처리하는 메서드를 지정
public ResponseEntity myCustomException(MyCustomException ex) {
ErrorResponse errorResponse = new ErrorResponse(ex.getErrorCode().getStatus(), ex.getErrorCode().getMessage());
return ResponseEntity.status(ex.getErrorCode().getStatus()).body(errorResponse);
}
}
@Service
@AllArgsConstructor
public class StoreService {
private StoreRepository storeRepository;
private HubRepository hubRepository;
@Transactional
public StoreResponseDto createStore(@Valid StoreRequestDto storeRequestDto, String userId, String role) {
if(!role.equals("ADMIN")){
throw new MyCustomException(ErrorCode.PERMISSION_DENIED);
}
Hub hub = hubRepository.findById(storeRequestDto.getHubId()).orElseThrow(
() -> new MyCustomException(ErrorCode.NOT_FOUND_HUB)
);
Store store = storeRepository.save(new Store(storeRequestDto, userId, hub));
return new StoreResponseDto(store);
}