完善 Dubbo Provider 异常过滤器,接入新的异常体系

This commit is contained in:
YunaiV
2020-07-19 01:34:44 +08:00
parent 32c1cfb3a7
commit c0407267b9
10 changed files with 90 additions and 51 deletions

View File

@@ -1,10 +1,11 @@
package cn.iocoder.mall.dubbo.core.filter;
import cn.iocoder.common.framework.exception.enums.GlobalErrorCodeEnum;
import cn.iocoder.common.framework.exception.GlobalException;
import cn.iocoder.common.framework.exception.ServiceException;
import cn.iocoder.common.framework.util.ExceptionUtil;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.service.GenericService;
import org.slf4j.Logger;
@@ -14,6 +15,9 @@ import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.lang.reflect.Type;
import static cn.iocoder.common.framework.exception.enums.GlobalErrorCodeConstants.*;
@Activate(group = CommonConstants.PROVIDER)
public class DubboProviderExceptionFilter implements Filter, Filter.Listener {
private Logger logger = LoggerFactory.getLogger(DubboProviderExceptionFilter.class);
@@ -32,26 +36,27 @@ public class DubboProviderExceptionFilter implements Filter, Filter.Listener {
// 1. 参数校验异常
if (exception instanceof ConstraintViolationException) {
exception = this.constraintViolationExceptionHandler((ConstraintViolationException) exception);
// 2. ServiceException 业务异常,转换成 ServiceException 业务异常,避免可能存在的反序列化问题
} if (!(exception instanceof ServiceException)) {
// 2. ServiceException 业务异常,因为不会有序列化问题,所以无需处理
} else if (exception instanceof ServiceException) {
// 3. 其它异常,转换成 ServiceException 业务异常,避免可能存在的反序列化问题
} else {
exception = this.defaultExceptionHandler(exception, invocation);
assert exception != null;
}
assert exception != null;
ServiceException serviceException = (ServiceException) exception;
// 根据不同的方法 schema 返回结果
// 第一种情况,返回参数类型是 CommonResult 的情况,则将 ServiceException 转换成 CommonResult
if (isReturnCommonResult(invocation)) {
// 清空异常
appResponse.setException(null);
// 设置结果
CommonResult exceptionResult = new CommonResult();
exceptionResult.setCode(serviceException.getCode());
exceptionResult.setMessage(serviceException.getMessage());
exceptionResult.setDetailMessage(serviceException.getDetailMessage());
appResponse.setValue(exceptionResult);
if (exception instanceof ServiceException) {
appResponse.setValue(CommonResult.error((ServiceException) exception));
} else {
appResponse.setValue(CommonResult.error((GlobalException) exception));
}
// 第二种情况,未包装成 CommonResult 的情况,则直接抛出 ServiceException 异常
} else {
appResponse.setException(serviceException);
appResponse.setException(exception);
}
} catch (Throwable e) {
logger.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
@@ -84,21 +89,20 @@ public class DubboProviderExceptionFilter implements Filter, Filter.Listener {
/**
* 处理 Validator 校验不通过产生的异常
*/
private ServiceException constraintViolationExceptionHandler(ConstraintViolationException ex) {
private GlobalException constraintViolationExceptionHandler(ConstraintViolationException ex) {
logger.warn("[constraintViolationExceptionHandler]", ex);
ConstraintViolation<?> constraintViolation = ex.getConstraintViolations().iterator().next();
return ServiceExceptionUtil.exception0(GlobalErrorCodeEnum.BAD_REQUEST.getCode(),
return new GlobalException(BAD_REQUEST.getCode(),
String.format("请求参数不正确:%s", constraintViolation.getMessage()));
}
/**
* 处理系统异常,兜底处理所有的一切
*/
private ServiceException defaultExceptionHandler(Throwable exception, Invocation invocation) {
private GlobalException defaultExceptionHandler(Throwable exception, Invocation invocation) {
logger.error("[defaultExceptionHandler][service({}) method({}) params({}) 执行异常]",
invocation.getServiceName(), invocation.getServiceName(), invocation.getArguments(), exception);
return ServiceExceptionUtil.exception0(GlobalErrorCodeEnum.INTERNAL_SERVER_ERROR.getCode(),
GlobalErrorCodeEnum.INTERNAL_SERVER_ERROR.getMessage())
return new GlobalException(INTERNAL_SERVER_ERROR)
.setDetailMessage(this.buildDetailMessage(exception, invocation));
}