이를 사용하면, 전역적으로 예외를 가로채서 처리할 수 있다.
@Getter
public class CustomException extends RuntimeException {
private final CodeInterFace codeInterFace;
public CustomException(CodeInterFace v) {
super(v.getMessage());
this.codeInterFace = v;
}
public CustomException(CodeInterFace v, String message) {
super(v.getMessage() + message);
this.codeInterFace = v;
}
public HttpStatus getHttpStatus() {
return codeInterFace.getHttpStatus();
}
}
명확한 메시지를 보내서, 예외의 원인을 정확하게 알려주는 게 좋다. 그래야 디버깅이 용이하다.
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User getUserById(Long id) {
try {
return userRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("User not found with id " + id));
} catch (DataAccessException e) {
throw new DatabaseAccessException("Error accessing the database", e);
}
}
}
이걸 보면, 예외를 가장 추상화가 높은 단계인 서비스단에서 한다. 그리고, 가장 낮은 단계인 글로벌 예외 핸들러에서 한다. 이를 통해 비즈니스 로직과 예외 처리 로직의 관심사르 분리할 수 있다.
특정한 상황에서는 예외를 처리하기 위해서, 폴백을 활용하는 것이 좋다.
db 예외 발생시, 메모리를 사용하도록 하는 방식이다.
@GetMapping("/users/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
User user = userRepository.findById(id)
.orElseGet(() -> {
log.warn("User not found in the database, falling back to cache");
return cacheService.getUser(id);
});
return ResponseEntity.ok(user);
}
DB에서 유저가 없다고 나오면, 메모리나 캐시에 유저가 있는지 확인하는 구조다. DB 장애가 발생해도, 서비스가 안정적으로 작동하도록 돕는 구조다.
public class ErrorResponse {
private final int errorCode;
private final String errorMessage;
public ErrorResponse(int errorCode, String errorMessage) {
this.errorCode = errorCode;
this.errorMessage = errorMessage;
}
public int getErrorCode() {
return errorCode;
}
public String getErrorMessage() {
return errorMessage;
}
}
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleResourceNotFoundException(ResourceNotFoundException ex) {
ErrorResponse errorResponse = new ErrorResponse(1001, ex.getMessage());
return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
}
}
참고자료