FeignClient的configuration失效处理

系统需要统一格式化返回调用异常的错误信息,所以编写了一个配置类实现了ErrorDecoder的接口,然后再@FeignClient的configuration加上了这个配置类,之前用得好好的,突然有一天不生效了,在这里记录排查处理过程。
1.首先查看到源码,feign.SynchronousMethodHandler#executeAndDecode
executeAndDecode

在1处发起请求之后,如果响应抛出的是IOException则直接返回了,不会调用到3处的自定义异常处理。
2.对于服务没有启动的情况,原生的异常类是UnknownHostException,在这里可能开启了重试,需要关掉,配置如下

spring:
  cloud:
    loadbalancer:
      retry:
        # 关闭自动重试,开启会导致feign ErrorDecoder配置失效
        enabled: false

3.对于接口超时,这里抛出SocketTimeoutException确实是IOException的子类,不想每个FallbackFactory都加上这段判断处理逻辑怎么办呢,可以使用AOP对这个方法进行切入统一处理

@Slf4j
@Aspect
@Component
public class FeignExceptionAspect {

    public FeignExceptionAspect(){}

    @Pointcut("execution(* com.hyp.*.api.factory.*.create(..))")
    public void pointcut(){}

    @Before("pointcut()")
    public void before(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        Object obj = args[0];
        if (obj == null) {
            return;
        }
        Throwable throwable = (Throwable)obj;
        if (throwable instanceof SocketTimeoutException || throwable instanceof RetryableException) {
            log.error("接口超时 {}", throwable.getMessage());
            throw new ServiceException("接口超时", HttpStatus.REQUEST_TIMEOUT.value());
        } else if (throwable instanceof UnknownHostException) {
            log.error("服务不可用 {}", throwable.getMessage());
            throw new ServiceException("服务不可用", HttpStatus.SERVICE_UNAVAILABLE.value());
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章