Feign ErrorDecoder 未被调用 - 如何配置 Feign 以使用它?
Feign ErrorDecoder is not invoked - how to configure feign to use it?
据我了解,当请求以状态代码 != 2xx 响应时,将调用 feign ErrorDecoder 的 decode() 方法。通过调试我的测试,我发现我的 CustomErrorDecoder 的 decode() 方法没有被调用,例如504或404。我尝试了两种配置方式:
要么将其作为 Bean 包含在客户端配置中:
@Bean
public CustomErrorDecoder customErrorDecoder() {
return new CustomErrorDecoder();
}
或者写入应用程序配置:
feign:
client:
config:
myCustomRestClientName:
retryer: com.a.b.some.package.CustomRetryer
errorDecoder: com.a.b.some.package.CustomErrorDecoder
这两种方式都不会调用 ErrorDecoder。我究竟做错了什么? Bean 正在实例化,我的 CustomErrorDecoder 看起来像这样:
@Component
public class CustomErrorDecoder implements ErrorDecoder {
private final ErrorDecoder defaultErrorDecoder = new Default();
@Override
public Exception decode(String s, Response response) {
Exception exception = defaultErrorDecoder.decode(s, response);
if (exception instanceof RetryableException) {
return exception;
}
if (response.status() == 504) {
// throwing new RetryableException to retry 504s
}
return exception;
}
}
更新:
我在 这个 git 存储库 中创建了一个最小的可复制示例。请查看提交历史以找到我尝试过的 3 种方法。
问题是你的 feign 客户端使用 feign.Response
作为 return 类型:
import feign.Param;
import feign.RequestLine;
import feign.Response;
public interface TestEngineRestClient {
@RequestLine(value = "GET /{uuid}")
Response getReport(@Param("uuid") String uuid);
}
在这种情况下,Feign 将其处理委托给开发人员 - 例如,您可以检索 HTTP 状态和响应主体并使用它做一些事情。
有兴趣的可以看看feign.SynchronousMethodHandler
、executeAndDecode
部分的源码
要解决此问题,请将 Response.class
替换为所需的类型,以防状态码 = 2xx 的正确响应(可能是某些 DTO class)。我制作了一个 PR,为了简单起见,我将其更改为 String
。
据我了解,当请求以状态代码 != 2xx 响应时,将调用 feign ErrorDecoder 的 decode() 方法。通过调试我的测试,我发现我的 CustomErrorDecoder 的 decode() 方法没有被调用,例如504或404。我尝试了两种配置方式:
要么将其作为 Bean 包含在客户端配置中:
@Bean
public CustomErrorDecoder customErrorDecoder() {
return new CustomErrorDecoder();
}
或者写入应用程序配置:
feign:
client:
config:
myCustomRestClientName:
retryer: com.a.b.some.package.CustomRetryer
errorDecoder: com.a.b.some.package.CustomErrorDecoder
这两种方式都不会调用 ErrorDecoder。我究竟做错了什么? Bean 正在实例化,我的 CustomErrorDecoder 看起来像这样:
@Component
public class CustomErrorDecoder implements ErrorDecoder {
private final ErrorDecoder defaultErrorDecoder = new Default();
@Override
public Exception decode(String s, Response response) {
Exception exception = defaultErrorDecoder.decode(s, response);
if (exception instanceof RetryableException) {
return exception;
}
if (response.status() == 504) {
// throwing new RetryableException to retry 504s
}
return exception;
}
}
更新:
我在 这个 git 存储库 中创建了一个最小的可复制示例。请查看提交历史以找到我尝试过的 3 种方法。
问题是你的 feign 客户端使用 feign.Response
作为 return 类型:
import feign.Param;
import feign.RequestLine;
import feign.Response;
public interface TestEngineRestClient {
@RequestLine(value = "GET /{uuid}")
Response getReport(@Param("uuid") String uuid);
}
在这种情况下,Feign 将其处理委托给开发人员 - 例如,您可以检索 HTTP 状态和响应主体并使用它做一些事情。
有兴趣的可以看看feign.SynchronousMethodHandler
、executeAndDecode
部分的源码
要解决此问题,请将 Response.class
替换为所需的类型,以防状态码 = 2xx 的正确响应(可能是某些 DTO class)。我制作了一个 PR,为了简单起见,我将其更改为 String
。