赞
踩
问题描述:当使用feign调用接口,出现400~500~的接口问题时。会出错feign:FeignException。(因为是错误,只能用catch Throwable,不可使用catch Exception捕获异常)导致程序无法继续运行。
问题原因:由于feign默认的错误处理类是FunFeignFallback会throw new AfsBaseExceptio导致外部无法捕获异常。
- import com.alibaba.fastjson.JSONObject;
- import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
- import com.ruicar.afs.cloud.common.core.util.IResponse;
- import feign.FeignException;
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.cglib.proxy.MethodInterceptor;
- import org.springframework.cglib.proxy.MethodProxy;
- import org.springframework.lang.Nullable;
-
- import java.lang.reflect.Method;
- import java.util.Objects;
-
- @Data
- @AllArgsConstructor
- @Slf4j
- public class FunFeignFallback<T> implements MethodInterceptor {
- private final Class<T> targetType;
- private final String targetName;
- private final Throwable cause;
-
- private static byte JSON_START = '{';
-
- @Nullable
- @Override
- public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
- String errorMessage = cause.getMessage();
- if (!(cause instanceof FeignException)) {
- log.error("FunFeignFallback:[{}.{}] serviceId:[{}] message:[{}]", targetType.getName(), method.getName(), targetName, errorMessage);
- log.error("feign调用失败", cause);
- return IResponse.fail("请求失败,请稍后再试");
- }
- int status = ((FeignException.FeignClientException) this.cause).status();
- boolean isAuthFail = (status==426||status==403||status==401)&&"afs-auth".equals(targetName);
- FeignException exception = (FeignException) cause;
- if(isAuthFail){
- log.warn("授权失败==========原始返回信息:[{}]",exception.contentUTF8());
- }else {
- log.error("FunFeignFallback:[{}.{}] serviceId:[{}] message:[{}]", targetType.getName(), method.getName(), targetName, errorMessage);
- log.error("", cause);
- log.error("原始返回信息{}",exception.contentUTF8());
- }
- if(method.getReturnType().equals(Void.class)){
- throw new AfsBaseException("接口调用失败");
- }
- if(method.getReturnType().equals(IResponse.class)){
- if(exception instanceof FeignException.Forbidden){
- return IResponse.fail("没有权限").setCode("403");
- }
- if(exception instanceof FeignException.NotFound){
- return IResponse.fail("请求路径不存在").setCode("404");
- }
- if(exception instanceof FeignException.BadRequest){
- return IResponse.fail("参数错误").setCode("400");
- }
-
- if(exception.content()==null||exception.content().length==0){
- return IResponse.fail("请求失败,请稍后再试");
- }
- if(JSON_START==exception.content()[0]){
- return JSONObject.parseObject(exception.content(),IResponse.class);
- }else{
- return IResponse.fail(exception.contentUTF8());
- }
- }else{
- try {
- if(method.getReturnType().equals(String.class)){
- return exception.contentUTF8();
- }else if(method.getReturnType().equals(JSONObject.class)){
- if(JSON_START==exception.content()[0]){
- return JSONObject.parseObject(exception.content(), JSONObject.class);
- }
- }else if(!method.getReturnType().equals(Object.class)){
- return JSONObject.parseObject(exception.content(), method.getReturnType());
- }
- if(JSON_START==exception.content()[0]){
- JSONObject jsonObject = JSONObject.parseObject(exception.content(), JSONObject.class);
- if(jsonObject.containsKey("code")&&jsonObject.containsKey("msg")) {
- return jsonObject.toJavaObject(IResponse.class);
- }
- }
- }catch (Throwable e){}
- throw new AfsBaseException("接口调用失败");
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- FunFeignFallback<?> that = (FunFeignFallback<?>) o;
- return targetType.equals(that.targetType);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(targetType);
-
- }
-
- }
问题解决:自定义feignFallback异常处理:
1.自定义异常处理 InvoiceApiFeignFallbackFactory
- @Component
- public class InvoiceApiFeignFallbackFactory implements FallbackFactory<InvoiceApiFeign> {
- @Override
- public InvoiceApiFeign create(Throwable throwable) {
- InvoiceApiFeignFallback invoiceApiFeignFallback = new InvoiceApiFeignFallback();
- invoiceApiFeignFallback.setCause(throwable);
- return invoiceApiFeignFallback;
- }
- }
2.feign调用 InvoiceApiFeignFallbackFactory
- /**
- * @description:
- * @author:
- * @date: 2020/8/14 10:32
- */
- @FeignClient(name = "invoice", url = "${}" ,fallbackFactory = InvoiceApiFeignFallbackFactory.class)
- public interface InvoiceApiFeign {
- /**
- *
- * @param dto
- * @return
- */
- @ApiOperation("获取业务数据API接口")
- @PostMapping(value = "/vi/check")
- @AfsFeignClear(true)//通过此注解防止添加内部token
- JSONObject InvoiceCheck(@RequestBody InvoiceCheckDto dto, @RequestHeader Map<String, String> headers);
- }
3.实现自定义报错处理
- /**
- * @author
- * @date
- */
- @Slf4j
- @Component
- public class InvoiceApiFeignFallback implements InvoiceApiFeign {
-
- @Setter
- private Throwable cause;
-
- /**
- * @param dto
- * @param headers
- * @return
- */
- @Override
- public JSONObject InvoiceCheck(InvoiceCheckDto dto, Map<String, String> headers) {
- log.error("feign 接口调用失败", cause);
- return null;
- }
- }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。