前言
在分布式服务的场景下,业务服务都将进行拆分,不同服务之前都会相互调用,如何做好异常处理是比较关键的,可以让业务人员在页面使用系统报错后,很清楚的看到服务报错的原因,而不是返回代码级别的异常报错,比如NullException、IllegalArgumentException、FeignExecption等异常报错,这样就会让非技术人员看到了一头雾水,从而很降低用户的体验感。
服务调用异常场景
这是一个很常规的服务链路调用异常,前端用户请求A服务,A服务再去请求B服务,B服务出现了异常,A服务返回的Fallback降级的报错异常,但是显然这个异常并不是很能让人理解。
这是feign服务之前调用异常的报错,通过FeignException内部的异常处理类进行处理。
重写Feign异常处理
首先我们可以通过实现feign的ErrorDecoder接口重写它的的decode方法,进行自定义异常处理,针对每个feign接口的异常报错,抛出自定义的exception将错误信息和错误码返回。
FeignExceptionConfiguration 自定义异常处理类
typescript复制代码@Slf4j
@Configuration
public class FeignExceptionConfiguration {
@Bean
public ErrorDecoder errorDecoder() {
return new UserErrorDecoder();
}
/**
* 重新实现feign的异常处理,捕捉restful接口返回的json格式的异常信息
*
*/
public class UserErrorDecoder implements ErrorDecoder {
@Override
public Exception decode(String methodKey, Response response) {
Exception exception = new MyException();
ObjectMapper mapper = new ObjectMapper();
//空属性处理
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_EMPTY);
//设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//禁止使用int代表enum的order来反序列化enum
mapper.configure(DeserializationConfig.Feature.FAIL_ON_NUMBERS_FOR_ENUMS, true);
try {
String json = Util.toString(response.body().asReader());
log.info("异常返回结果:"+ JSON.toJSONString(json));
exception = new RuntimeException(json);
if (StringUtils.isEmpty(json)) {
return null;
}
FeignFaildResult result = mapper.readValue(json, FeignFaildResult.