FeignClient dismiss404 동작원리
개요
Feign client ErrorDecoder 분석에 이어 dismiss404 옵션에 대해서 정리해보고자 합니다.
Feign Client의 ErrorDecoder
400~ 500번대의 상태코드를 받는 경우 FeignException을 반환합니다.
따라서 404가 발생한 경우에도 FeignClientException을 반환합니다.
404의 경우에 예외를 던지지 않도록 수정
@FeignClient(
name = "localTestFeign",
url = "http://localhost:8080",
dismiss404 = true,
)
dismiss404에 대한 docs를 읽어보면 404 상태코드를 받으면 FeignException을 던지는 대신 decode 할지를 true/false로 결정할 수 있습니다.
Feign Builder
public B dismiss404() {
this.dismiss404 = true;
return thisB;
}
Feign은 Builder를 통해 구성되고 Builder는 BaseBuilder 클래스를 상속받고있습니다.
BaseBuilder 클래스에는 dismiss를 세팅하는 부분이 존재합니다.
의도적으로 404 발생시키는 응답 호출하기
@Override
public Object decode(Response response, Type type) throws IOException {
if (!isOptional(type)) {
return delegate.decode(response, type);
}
if (response.status() == 404 || response.status() == 204) {
return Optional.empty();
}
Type enclosedType = Util.resolveLastTypeParameter(type, Optional.class);
return Optional.ofNullable(delegate.decode(response, enclosedType));
}
OptionalDecoder클래스가 응답을 받아 처리합니다.
dismiss404가 false라면
final boolean shouldDecodeResponseBody = (response.status() >= 200 && response.status() < 300)
|| (response.status() == 404 && dismiss404 && !isVoidType(returnType));
ResponseHandler 클래스에서 http status가 404이면서 dismiss404가 false라면 ErrorDecoder로 호출합니다.
if (!shouldDecodeResponseBody) {
throw decodeError(configKey, response);
}
private Exception decodeError(String methodKey, Response response) {
try {
return errorDecoder.decode(methodKey, response);
} finally {
ensureClosed(response.body());
}
}
decodeError는 Exception을 반환하며 이 기능은 ErrorDecoder가 처리하게 됩니다.
이로써 dismiss404 옵션이 어디에 활용되는지 알아보았습니다.
마무리
feign에는 dismiss라는 옵션이 있다.
해당옵션을 false로 설정되면 ResponseHandler클래스가 404 상태코드 발생 시 ErrorDecoder를 호출한다.
해당옵션이 true라면 OptionalDecoder클래스가 응답을 처리한다.
참고자료
https://junuuu.tistory.com/815