FeignErrorDecoder:对feign调用异常进行封装
@Slf4j
@Configuration
public class FeignErrorDecoder extends ErrorDecoder.Default {
@Override
public Exception decode(String methodKey, Response response) {
Exception exception = super.decode(methodKey, response);
if (exception instanceof RetryableException) {
return exception;
}
try {
if (exception instanceof FeignException && ((FeignException) exception).responseBody().isPresent()) {
ByteBuffer responseBody = ((FeignException) exception).responseBody().get();
String bodyText = StandardCharsets.UTF_8.newDecoder().decode(responseBody.asReadOnlyBuffer()).toString();
ExceptionInfo exceptionInfo = JSON.parseObject(bodyText, ExceptionInfo.class);
Integer code = Optional.ofNullable(exceptionInfo.getCode()).orElse(ResultCodeEnum.ERROR.getCode());
String message = Optional.ofNullable(exceptionInfo.getMessage()).orElse(ResultCodeEnum.ERROR.getMessage());
return new BusinessException(code, message);
}
} catch (Exception ex) {
log.error(ex.getMessage(), ex);
}
return exception;
}
}
@RestControllerAdvice和@ExceptionHandler对web模块进行异常封装
@Slf4j
@RestControllerAdvice
public class WebGlobalExceptionHandler {
@ExceptionHandler({FeignException.class})
@ResponseBody
public R<?> feignExceptionHandler(FeignException exception) {
log.error(exception.getMessage(), exception);
return R.error(exception.getMessage());
}
@ExceptionHandler({RuntimeException.class})
@ResponseBody
public R<?> runtimeExceptionHandler(RuntimeException exception) {
log.error(exception.getMessage(), exception);
return R.error(exception.getMessage());
}
@ExceptionHandler({Exception.class})
@ResponseBody
public R<?> exceptionHandler(Exception exception) {
log.error(exception.getMessage(), exception);
return R.error(exception.getMessage());
}
@ExceptionHandler({BusinessException.class})
public R<?> businessExceptionHandler(BusinessException exception) {
log.error(exception.getMessage(), exception);
return R.error(exception.getCode(), exception.getMessage());
}
@ExceptionHandler({BindException.class})
@ResponseBody
public R<?> bindExceptionHandler(BindException exception) {
List<FieldError> fieldErrors = exception.getBindingResult().getFieldErrors();
String errorMessage = fieldErrors.get(0).getDefaultMessage();
log.error(errorMessage, exception);
return R.error(ResultCodeEnum.ERROR_PARAMETER.getCode(), errorMessage);
}
@ExceptionHandler({MethodArgumentNotValidException.class})
public R<?> validateExceptionHandler(MethodArgumentNotValidException exception) {
List<FieldError> fieldErrors = exception.getBindingResult().getFieldErrors();
String errorMessage = fieldErrors.get(0).getDefaultMessage();
log.error(errorMessage, exception);
return R.error(ResultCodeEnum.ERROR_PARAMETER.getCode(), errorMessage);
}
}
@ControllerAdvice 统一封装web的返回值
@ControllerAdvice(basePackages = "tech.xproject.web.manager")
public class ResponseHandler implements ResponseBodyAdvice<Object> {
/**
* 是否支持advice功能
* treu=支持,false=不支持
*/
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
return true;
}
/**
*
* 处理response的具体业务方法
*/
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
if(o.getClass().equals(R.class)){
//这里如果web有异常会优先被统一异常处理先捕获,所以如果判断为R类型,直接返回
return oR;
}
return R.success(o);
}
}
晚点贴上完整demo
参考文章:
Feign自定义ErrorDecoder错误时返回统一结构
https://blog.csdn.net/new9xgh/article/details/107934862