自定义拦截feign错误
Posted 信行合一
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义拦截feign错误相关的知识,希望对你有一定的参考价值。
定义Feign错误处理的Decoder
package com.test.admin.util;
import com.test.admin.util.exception.AdminFeignException;
import feign.Response;
import feign.codec.ErrorDecoder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@Slf4j
public class FeignErrorDecoder implements ErrorDecoder
@Override
public AdminFeignException decode(String methodKey, Response response)
log.error("=== 调用FeignClient报错=====");
log.error("=== FeignClient url:=====", response.request().url());
log.error("=== FeignClient method:=====", methodKey);
log.error("=== FeignClient error:=====", response.body());
log.error("=== 调用FeignClient报错=====");
if (StringUtils.isBlank(response.reason()))
return new AdminFeignException(response.status(), "服务端接口:" + methodKey + "报错!", response.body().toString());
return new AdminFeignException(response.status(), response.reason(), "");
生成自定义Decoder实例
import com.test.admin.util.FeignErrorDecoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 打印feign log
* @Author ztd
*/
@Configuration
public class FeignClientConfig
@Bean
public FeignErrorDecoder feignErrorDecoder()
return new FeignErrorDecoder();
这样后面出现了Feign相关的错误之后我们就可以通过拦截FeignErrorDecoder错误来明确处理Feign的错误了
举例如下:
@ExceptionHandler(value = Exception.class)
@ResponseBody
public AdminResponse defaultErrorHandler(HttpServletRequest req, Exception e, HttpServletResponse response)
log.error("====ExceptionHandler Exception 报错====", e);
if(e instanceof RuntimeException)
if(StringUtils.isNotBlank(e.getMessage()))
if (e.getMessage().contains("com.netflix.client.ClientException"))
String[] errorArr = e.getMessage().split(":");
return AdminResponse.fail("服务端服务不存在:" + errorArr[2]);
else if(e instanceof RetryableException)
String[] errorArr = e.getMessage().split("executing");
return AdminResponse.fail("服务端服务链接超时:" + errorArr[1]);
if (e instanceof UndeclaredThrowableException)
if (((UndeclaredThrowableException) e).getUndeclaredThrowable() instanceof AdminFeignException)
AdminFeignException adminFeignException = (AdminFeignException) ((UndeclaredThrowableException) e).getUndeclaredThrowable();
AdminResponse fail = AdminResponse.fail(adminFeignException.getMessage());
fail.setExtendData(adminFeignException.getExtra());
return fail;
return AdminResponse.fail(e.getMessage());
if(e instanceof ClientException || e instanceof FeignException)
// 处理服务端 服务不存在的问题
response.setStatus(HttpStatuCodes.CLIENT_NOT_EXISTS);
return AdminResponse.fail("服务端服务不存在:" + e.getMessage());
else if(e instanceof NullPointerException)
return AdminResponse.fail("NullPointerException: " + e.getMessage());
else if(e instanceof JSONException)
return AdminResponse.fail("Json解析报错: " + e.getMessage());
return AdminResponse.fail("接口内部错误:" + e.getMessage());
package com.test.admin.util.response;
import com.test.admin.util.StringUtil;
import com.test.platform.foundation.Response;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
/**
* 接口返回实体
*/
@Data
@Slf4j
public class AdminResponse
public static final int SUCCESS_STATUS = 0;
public static final int FAIL_STATUS = 1;
/**
* 返回状态值
*/
private int status;
/**
* 返回描述信息
*/
private String message;
/**
* 返回数据
*/
private Object Data;
/**
* 如果需要返回额外的信息,可以在这里填充
*/
private Object extendData;
public AdminResponse(int status)
this.status = status;
public boolean isSuccess()
return this.status == SUCCESS_STATUS;
public static final AdminResponse success()
return success(null);
public static final AdminResponse success(Object data)
return success(data, null);
public static final AdminResponse success(Object data, Object extend)
return success(data, extend, StringUtil.EMPTY);
public static final AdminResponse success(Object data, Object extend, String msg)
AdminResponse response = new AdminResponse(SUCCESS_STATUS);
response.setData(data);
response.setExtendData(extend);
response.setMessage(msg);
return response;
public static final AdminResponse fail(String message)
return fail(FAIL_STATUS, message);
/**
* 根据给定的 format + message 生成消息
* @param format
* @param message
* @return
*/
public static final AdminResponse fail(String format, String message)
message = String.format(format, message);
return fail(FAIL_STATUS, message);
public static final AdminResponse fail(String message, String logMsg, String exceptionMsg)
log.error(logMsg, exceptionMsg);
return fail(FAIL_STATUS, message);
public static final AdminResponse fail(int status, String message)
AdminResponse response = new AdminResponse(status);
response.setMessage(message);
return response;
public static final AdminResponse fail(Object data)
AdminResponse response = fail(null);
response.setData(data);
return response;
public static final AdminResponse convertResponse(Response response, String msg)
if (HttpStatus.OK.value() == response.getCode())
return AdminResponse.success(response.getData());
return AdminResponse.fail(msg);
以上是关于自定义拦截feign错误的主要内容,如果未能解决你的问题,请参考以下文章
Spring Cloud Alibaba - 14 OpenFeign自定义配置 + 调用优化 + 超时时间
spring cloud 服务A调用服务B自定义token消失,记录