본문 바로가기
BackEnd/Project

[RealPJ] Ch02. 실무 스타일로 Feign Client 사용해보기 - ErrorDecoder

by 개발 Blog 2024. 8. 31.

공부 내용을 정리하고 앞으로의 학습에 이해를 돕기 위해 작성합니다.

이번 포스팅에서는 Feign Client에서 에러를 처리하기 위한 ErrorDecoder 설정을 진행한다. 이를 통해 Feign Client가 외부 API 요청 시 발생할 수 있는 에러를 적절히 처리할 수 있다.

 

1. ErrorDecoder 설정

먼저, DemoController에 새로운 엔드포인트를 추가하여 에러 처리 기능을 테스트할 수 있도록 한다.

package dev.be.feign.controller;

import dev.be.feign.service.DemoService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RestController
public class DemoController {

    private final DemoService demoService;
	
    ...

    @GetMapping("/error")
    public String errorDecoderController() {
        return demoService.errorDecoder();
    }
}

 

DemoService 클래스에도 관련 메서드를 추가하여, Feign Client를 이용한 에러 처리 로직을 호출한다.

package dev.be.feign.service;

import dev.be.feign.common.dto.BaseRequestsInfo;
import dev.be.feign.common.dto.BaseResponseInfo;
import dev.be.feign.feign.client.DemoFeignClient;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class DemoService {

    private final DemoFeignClient demoFeignClient;

    ...
    
   public String errorDecoder() {
        demoFeignClient.callErrorDecoder();
        return "post";
    }
}

 

DemoFeignClient 인터페이스에 /error 경로에 대한 요청 메서드를 추가한다.

package dev.be.feign.feign.client;

import dev.be.feign.common.dto.BaseRequestsInfo;
import dev.be.feign.common.dto.BaseResponseInfo;
import dev.be.feign.feign.config.DemoFeignConfig;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@FeignClient(
        name = "demo-client",
        url = "${feign.url.prefix}",
        configuration = DemoFeignConfig.class
)
public interface DemoFeignClient {
    ...
    
    @GetMapping("/error")
    ResponseEntity<BaseResponseInfo> callErrorDecoder();
}

 

TargetController에도 관련 코드를 추가하여, 에러 응답을 반환하는 엔드포인트를 만든다.

package dev.be.feign.controller;

import dev.be.feign.common.dto.BaseRequestsInfo;
import dev.be.feign.common.dto.BaseResponseInfo;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/target_server")
public class TargetController {
    
    ...

    @GetMapping("/error")
    public ResponseEntity<BaseResponseInfo> demoErrorDecoder() {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
    }

}

 

2. ErrorDecoder 구현

DemoFeignErrorDecoder 클래스를 생성하여, 특정 상태 코드에 대한 에러 처리 로직을 구현한다.

package dev.be.feign.feign.decoder;

import feign.Response;
import feign.codec.ErrorDecoder;
import org.springframework.http.HttpStatus;

public class DemoFeignErrorDecoder implements ErrorDecoder {
    private final ErrorDecoder errorDecoder = new Default();

    @Override
    public Exception decode(String methodKey, Response response) {
        HttpStatus httpStatus = HttpStatus.resolve(response.status());

        if (httpStatus == HttpStatus.NOT_FOUND) {
            System.out.println("[DemoFeignErrorDecoder] Http Status = " + httpStatus);
            throw new RuntimeException(String.format("[RuntimeException] Http Status is %s", httpStatus));
        }

        return errorDecoder.decode(methodKey, response);
    }
}

 

이 ErrorDecoder를 Spring Bean으로 등록한다.

package dev.be.feign.feign.config;

import dev.be.feign.feign.decoder.DemoFeignErrorDecoder;
import dev.be.feign.feign.interceptor.DemoFeignInterceptor;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DemoFeignConfig {
	...

    @Bean
    public DemoFeignErrorDecoder demoFeignErrorDecoder() {
        return new DemoFeignErrorDecoder();
    }
}

 

 

3. 실행 결과

curl localhost:8080/error 명령어를 실행하면, 404 NOT_FOUND 상태 코드가 발생하게 된다. 이 에러는 DemoFeignErrorDecoder에서 처리되며, 콘솔에 해당 에러에 대한 로그가 출력된다. 로그에는 시스템 아웃 로그와 함께 RuntimeException이 발생한 내역이 출력되며, 의도한 대로 에러가 처리되고 로그로 기록되는 것을 확인할 수 있다.

의도한 것과 의도하지 않은 에러들이 섞여있긴 하지만 시스템 아웃 로그 출력과 runtimeexception 로그가 출력이 되는 것을 확인할 수 있다.

이 포스팅을 통해 Feign Client에서 발생하는 에러를 효과적으로 처리하고 로그를 남기는 방법을 학습했다. 이를 통해 예기치 않은 에러에 대해 적절히 대응할 수 있는 실무적인 역량을 강화할 수 있었다. Feign의 다양한 기능을 활용하여 더 안정적이고 관리하기 쉬운 클라이언트 애플리케이션을 개발할 수 있게 되었다.