FeignClient服務器拋出異常客戶端處理方案

FeignClient服務器拋出異常客戶端處理

在使用feign進行遠程方法調用時,如果遠程服務端方法出現異常,客戶端有時需要捕獲,並且把異常信息返回給前端,而如果在開啟熔斷之後,這個異常會被消化,所以說,如果希望拿到服務端異常,

feign.hystrix.enable需要設置為false,而當不開熔斷時,我們也有幾種方法把拿到服務端的異常信息,下面總結一下。

feign異常攔截器

註冊一個Bean對象,當feign調用出現異常的時候,會觸發這個方法:

import com.test.JsonUtils;
import feign.Response;
import feign.Util;
import feign.codec.ErrorDecoder;
import io.test.BadRequestException;
import io.test.InternalServerErrorException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import static feign.FeignException.errorStatus;

/**
 * @author 飄逝才子
 * @date 2020/11/05
 * @description
 */
@Configuration
public class FeignClientErrorDecoder implements ErrorDecoder {
    private Logger logger = LoggerFactory.getLogger(FeignClientErrorDecoder.class);

    @Override
    public Exception decode(String methodKey, Response response) {
        Map<String, Object> jsonBody = new HashMap<>();
        jsonBody.put("message", "Internal server error");
        try {
            String body = Util.toString(response.body().asReader());
            jsonBody = JsonUtils.toMap(body);
        } catch (IOException e) {
            logger.error("feign.IOException", e);
        }
        assert jsonBody != null;
        if (response.status() >= 400 && response.status() < 500) {
            throw new BadRequestException(jsonBody.get("message").toString());
        }

        if (response.status() >= 500) {
            throw new InternalServerErrorException(jsonBody.get("message").toString());
        }

        return errorStatus(methodKey, response);
    }
}

註意,使用這個方式,需要在熔斷器關閉時才起作用,因為它們的執行過程是,先走這個攔截器,再走熔斷的fallback,所以這個異常會被熔斷吞掉,返回狀態為200,返回值為你的fallback的默認值。

FeignClient異常合集Mark

問題1

feignClient調用報異常cause:Content-Type cannot contain wildcard type ‘*’

是因為遠程調用的時候入參識別不瞭application/json

解決辦法:在方法上加上類型即可consumes = MediaType.APPLICATION_JSON_VALUE

 @RequestMapping(value = "/xxx/xxx/xxx/xxx/xxx/xxx/result",method = RequestMethod.GET,  consumes = MediaType.APPLICATION_JSON_VALUE)
    ResponseResult xxx(TaskParam taskParam);

問題2

fallback 與fallbackFactory的使用

fallbackFactory:拋出異常可查看,一般看裡面拋出的異常日志即可判斷遠程調用的問題所在。

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: