【Spring Cloud】spring cloud feign自定义捕获异常

feign client 2.x 默认异常

public static FeignException errorStatus(String methodKey, Response response) {
    String message = format("status %s reading %s", response.status(), methodKey);
    try {
      Object body = toString.decode(methodKey, response, String.class);
      if (body != null) {
        response = Response.create(response.status(), response.reason(), response.headers(), body.toString());
        message += "; content:\n" + body;
      }
    } catch (IOException ignored) { // NOPMD
    }
    return new FeignException(message);
  }

也就是当访问异常时,返回信息大概是这样的:

{
	"timestamp": "2019-02-24 17:15:19",
	"status": 500,
	"error": "Internal Server Error",
	"message": "status 400 reading PaymentInterface#methodName(ParamType,ParamType)
     content: {"type":"http://httpstatus.es/404","title":"未找到资源","status":400,"detail":"这里是详细的异常信息"} ",
	"path": "/oauth/token"
}

我遇到的问题是,只给我返回了状态码和methodKey

{"message":"status 400 reading KFCClient#instanceProcess(String,String,String,String)",
"detail":"feign.FeignException: status 400 reading KFCClient#instanceProcess(String,String,String,String)",
"code":0}

所以尝试自定义异常返回信息:

  1. 自定义ErrorDecoder
    注意需要@Configuration
@Configuration
public class FeignErrorDecoder implements ErrorDecoder {
    @Override
    public Exception decode(String methodKey, Response response) {
        try {
            String rsb = Util.toString(response.body().asReader());
            JSONObject jsonObject = new JSONObject(rsb);
            String message ="[ "+ methodKey+ " ] "+jsonObject.getString("message");
            return new FeignBaseException(message,jsonObject.getInt("status"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return decode(methodKey,response);
    }
}
  1. 自定义一个异常对象
public class FeignBaseException extends RuntimeException {
    private int status ;

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public FeignBaseException() {
    }

    public FeignBaseException(String message, int status) {
        super(message);
        this.status = status;
    }

    public FeignBaseException(String message) {
        super(message);
    }

    public FeignBaseException(String message, Throwable cause) {
        super(message, cause);
    }

    public FeignBaseException(Throwable cause) {
        super(cause);
    }

    public FeignBaseException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

将这两个文件直接放到工程中即可,不需要其它配置

这才是真正的错误信息,如下(格式可自定义):

{
    "message": "[ KFCClient#instanceProcess(String,String,String,String) ] Internal error: Exception while invoking TTListener: Exception while invoking TTListener: The tenant did NOT exists!",
    "detail": "com.asiainfo.cm.restserver.exception.FeignBaseException: [ KFCClient#instanceProcess(String,String,String,String) ] Internal error: Exception while invoking TTListener: Exception while invoking TTListener: The tenant did NOT exists!!",
    "code": 0
}

参考链接:
https://blog.51cto.com/4925054/2354156?source=dra
https://github.com/OpenFeign/feign/wiki/Custom-error-handling

你可能感兴趣的:(spring,cloud,Java)