Feign调用全局异常处理解决方案

网友投稿 2214 2023-01-05

Feign调用全局异常处理解决方案

Feign调用全局异常处理解决方案

异常信息形如:

TestService#addRecord(ParamVO) failed and no fallback available.;

对于failed and no fallback available.这种异常信息,是因为项目开启了熔断:

feign.hystrix.enabled: true

当调用服务时抛出了异常,却没有定义fallback方法,就会抛出上述异常。由此引出了第一个解决方式。

解决方案:

自定义Feign解析器:

import com.alibaba.fastjson.JSONException;

import com.alibaba.fastjson.JSONObject;

import com.crecgec.baseboot.jsoncore.exception.BaseException;

import feign.Response;

import feign.Util;

import feign.codec.ErrorDecoder;

import org.springframework.context.annotation.Configuration;

import java.io.IOException;

@Configuration

public class FeignErrorDecoder implements ErrorDecoder {

@Override

public Exception decode(String methodKey, Response response) {

try {

// 这里直接拿到我们抛出的异常信息

String message = Util.toString(response.body().asReader());

try {

JSONObject jsonObject = JSONObject.parseObject(message);

return new BaseException(jsonObject.getString("resultMsg"), jsonObject.getInteger("resultCode"));

} catch (JSONException e) {

e.printStackTrace();

DzGhejGxYI }

} catch (IOException ignored) {

}

return decode(methodKey, response);

}

}

定义系统的异常类

public class BaseException extends RuntimeException {

private int status ;

public int getStatus() {

return status;

}

public void setStatus(int status) {

this.status = status;

}

public BaseException() {

}

public BaseException(String message, int status) {

super(message);

this.status = status;

}

public BaseException(String message) {

super(message);

}

public BaseException(String message, Throwable cause) {

super(message, cause);

}

public BaseException(Throwable cause) {

super(cause);

}

public BaseException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {

super(message, cause, enableSuppression, writableStackTrace);

}

}

统一异常拦截转换对应的异常信息返回前端

public class ResultSet {

/**

* 返回的状态码

*/

private Integer resultCode;

/**

* 返回的消息

*/

private String resultMsg;

/**

* 返回的数据

*/

private Object data;

public ResultSet() {

}

public ResultSet(Integer resultCode, String resultMsg) {

this.resultCode = resultCode;

this.resultMsg = resultMsg;

}

public ResultSet(Integer resultCode, String resultMsg, Object data) {

this.resultCode = resultCode;

this.resultMsg = resultMsg;

this.data = data;

}

public Integer getResultCode() {

return resultCode;

}

public void sethttp://ResultCode(Integer resultCode) {

this.resultCode = resultCode;

}

public String getResultMsg() {

return resultMsg;

}

public void setResultMsg(String resultMsg) {

this.resultMsg = resultMsg;

}

public Object getData() {

return data;

}

public void setData(Object data) {

this.data = data;

}

}

全局异常类处理配置

@ExceptionHandler(value = BaseException.class)

public ResultSet defaultErrorHandler(HttpServletRequest req, HttpServletResponse resp, BaseException e) {

ResultSet resultSet = new ResultSet();

if (e.getStatus() == 400) {

resultSet.setResultCode(-1);

resultSet.setResultMsg(e.getMessage());

resultSet.setData(null);

resp.setStatus(400);

} else {

resp.setStatus(500);

if(logger.isErrorEnabled()){

logger.error("系统异常,请联系系统开发人员进行处理", e);

}

resultSet.setResultCode(-1);

resultSet.setResultMsg(e.getMessage());

resultSet.setData(null);

}

return resultSet;

}

这样就能完成了feign接收异常处理的自定义异常信息!

统一处理@FeignClient调用接口异常----原样抛出

第三方系统调用我方系统@FeignClient接口时报错

com-flix.hystrix.exception.HystrixRuntimeException: WorkFlowTaskOperateService#processWorkFlowTaskSyncCallback(TaskProcessDTO) failed and no fallback available.

我方系统出现FeignException.

第三方调用者抛出的异常:HystrixRuntimeException

一检查我们系统确实没有指定fallback和configuration,并且调用方开启了feign.hystrix.enabled: true

@FeignClient(value = "taxplan-workflow")

修改方法:

第三方调用在Application.java添加处理Feign异常的全局处理方法

@Bean

public Feign.Builder feignBuilder() {

return Feign.builder().requestInterceptor(new RequestInterceptor() {

@Override

public void apply(RequestTemplate requestTemplate) {

Map customHeaders = WebUtils.getCustomHeaders();

customHeaders.forEach((k, v) -> {

requestTemplate.header(k, v);

});

}

}).errorDecoder(new CustomErrorDecoder());

}

这里使用了RequestInterceptor-,可以定制请求头,如果不想定制,可以改为

return Feign.builder().errorDecoder(new CustomErrorDecoder());

实现ErrorDecoder接口,其中ExceptionCode是枚举类.

public Exception decode(String methodKey, Response response) {

if (response.status() >= 400 && response.status() <= 499) {

return new BaseBizException(ExceptionCode.CALL_INNER_ERROR, "Client error.httpStatusCode:" + response.status());

} else {

if (response.status() >= 500 && response.status() <= 599 && response.body() != null) {

try {

String content = CharStreams.toString(new InputStreamReader(response.body().asInputStream(), StandardCharsets.UTF_8));

Map responseBody = (Map) JSONObject.parseObject(content, Map.class);

if (responseBody.containsKey("code")) {

return new BaseBizException(responseBody.get("code").toString(), Objects.toString(responseBody.get("msg")));

}

} catch (Exception var5) {

}

}

return new BaseBizException(ExceptionCode.CALL_INNER_ERROR);

}

}

ExceptionCode枚举类如下:可以自定义增加删除

public enum ExceptionCode {

ILLEGAL_STATE(4001, "非法访问"),

PARAM_REQUIRED(4002, "参数不能为空"),

PARAM_FORMAT_ILLEGAL(4003, "参数格式错误"),

REQUEST_DATA_DUPLICATION(4004, "重复请求"),

REQUEST_DATA_ERROR(4005, "请求数据错误"),

REQUEST_DATA_NOT_MATCH(4006, "请求数据不一致"),

RECORD_NOT_EXIST(5001, "记录不存在"),

RECORD_EXISTED(5002, "记录已存在"),

RECORD_ILLEGAL_STATE(5003, "数据异常"),

BALANCE_NOT_ENOUGH(5103, "余额不足"),

CALL_INNER_ERROR(5800, "调用内部服务接口异常"),

THIRD_PART_ERROR(5801, "调用第三方接口异常"),

SYSTEM_ERROR(9999, "系统异常");

public final int code;

public final String defaultMessage;

private ExceptionCode(int code, String defaultMessage) {

this.code = code;

this.defaultMessage = defaultMessage;

}

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:软件技术和软移动应用开发(软件开发和移动应用开发)
下一篇:贸易金融小程序有哪些平台(小型贸易用什么软件)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~