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());
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章