@ -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 ( s erviceE xception) ;
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 Service Exception constraintViolationExceptionHandler ( ConstraintViolationException ex ) {
private Global Exception 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 Service Exception defaultExceptionHandler ( Throwable exception , Invocation invocation ) {
private Global Exception 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 ) ) ;
}