OpenFeign 공통 예외처리
IT IT 인터넷 spring mvc openFeign@ControllerAdvice
http://java21.net/blog/marco?post_id=2423
OpenFeign 공통 예외처리
Feign 클라이언트에서 발생하는 예외를 공통적으로 처리하는 방법을 소개하겠습니다. Spring에서 제공하는 예외 처리 메커니즘을 활용하여 Feign의 예외를 공통적으로 처리할 수 있습니다. 이를 통해 여러 서비스에서 발생할 수 있는 예외를 중앙에서 처리하고, 중복 코드를 방지할 수 있습니다.
1. @ControllerAdvice를 이용한 공통 예외 처리
Spring에서 @ControllerAdvice를 사용하여 전역적으로 예외를 처리할 수 있습니다. Feign 클라이언트에서 발생한 예외도 이를 통해 처리할 수 있습니다. Feign은 FeignException을 던지므로 이를 처리하는 방법을 소개합니다.
예외 처리 클래스 정의
@ControllerAdvice를 사용하여 Feign 예외를 처리하는 클래스는 다음과 같습니다.
import feign.FeignException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(FeignException.class)
public ResponseEntity<String> handleFeignException(FeignException ex) {
// FeignException이 발생한 경우 공통적으로 처리
HttpStatus status = HttpStatus.valueOf(ex.status());
String errorMessage = "Feign 클라이언트 호출 중 오류 발생: " + ex.getMessage();
// 필요에 따라 로깅 추가
// 로그 예시: logger.error("Feign 호출 오류: ", ex);
return new ResponseEntity<>(errorMessage, status);
}
// 다른 공통 예외 처리도 추가할 수 있습니다.
}
@RestControllerAdvice: 이 어노테이션은 예외를 처리하는 컨트롤러에서 발생하는 예외를 처리합니다.@ExceptionHandler(FeignException.class):FeignException을 처리하는 메서드를 지정합니다.FeignException은 Feign 클라이언트에서 발생할 수 있는 예외의 최상위 클래스입니다.ResponseEntity: 클라이언트에 반환할 HTTP 상태 코드와 메시지를 설정합니다.
2. FeignException 종류
FeignException은 여러 종류가 있을 수 있습니다. 상태 코드에 따라 다른 처리 로직을 구현하고 싶다면, status() 메서드를 통해 HTTP 상태 코드를 확인하고 해당 코드를 기반으로 분기할 수 있습니다.
예를 들어, HTTP 404(Not Found)와 500(Internal Server Error) 상태 코드를 구분하여 처리할 수 있습니다.
@ExceptionHandler(FeignException.class)
public ResponseEntity<String> handleFeignException(FeignException ex) {
HttpStatus status = HttpStatus.valueOf(ex.status());
String errorMessage;
if (status == HttpStatus.NOT_FOUND) {
errorMessage = "요청한 리소스를 찾을 수 없습니다. (404 오류)";
} else if (status == HttpStatus.INTERNAL_SERVER_ERROR) {
errorMessage = "서버 내부 오류가 발생했습니다. (500 오류)";
} else {
errorMessage = "Feign 클라이언트 호출 중 오류 발생: " + ex.getMessage();
}
return new ResponseEntity<>(errorMessage, status);
}
3. Fallback을 사용한 예외 처리
Feign의 fallback 기능을 활용하여 클라이언트가 호출하는 외부 서비스에서 오류가 발생할 경우 대체 응답을 제공할 수 있습니다. 이를 통해 애플리케이션의 안정성을 높일 수 있습니다.
@FeignClient(name = "example-client", url = "https://api.example.com", fallback = ExampleClientFallback.class)
public interface ExampleClient {
@GetMapping("/data")
String getData();
}
ExampleClientFallback 클래스는 Feign 클라이언트 호출이 실패할 경우 대체 응답을 제공하는 클래스입니다.
import org.springframework.stereotype.Component;
@Component
public class ExampleClientFallback implements ExampleClient {
@Override
public String getData() {
return "Fallback response: 외부 API 호출에 실패했습니다.";
}
}
4. 예외 처리와 로깅
Feign 예외 처리 시, 로그를 기록하여 디버깅에 도움이 되도록 할 수 있습니다. 예외를 처리하는 GlobalExceptionHandler 클래스에서 예외를 로깅하면, 어떤 요청에서 오류가 발생했는지 추적할 수 있습니다.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(FeignException.class)
public ResponseEntity<String> handleFeignException(FeignException ex) {
HttpStatus status = HttpStatus.valueOf(ex.status());
String errorMessage = "Feign 클라이언트 호출 중 오류 발생: " + ex.getMessage();
// 예외 로깅
logger.error("Feign 호출 오류: 상태 코드 = {}, 메시지 = {}", ex.status(), ex.getMessage());
return new ResponseEntity<>(errorMessage, status);
}
}
5. 결론
Feign에서 발생하는 예외를 공통적으로 처리하는 방법은 @ControllerAdvice와 @ExceptionHandler를 활용하여 중앙에서 처리하는 것입니다. 이를 통해 코드의 중복을 줄이고, 예외 처리 로직을 한 곳에서 관리할 수 있습니다. 또한, fallback을 사용하여 서비스가 실패할 경우 대체 응답을 제공하고, Feign 클라이언트에서 발생하는 오류를 로깅하여 디버깅에 도움이 되도록 할 수 있습니다.
이와 같은 예외 처리 방법을 사용하면 안정적이고 일관된 방식으로 서비스 간의 통신 오류를 처리할 수 있습니다.