dubbo
dubbo copied to clipboard
The dubbo method parameter validation exception message is swallowed by ValidationException
- [ ] I have searched the issues of this repository and believe that this is not a duplicate.
Environment
- Dubbo version: 3.0.10
- Operating System version: MacOS 12.5
- Java version: 11
Steps to reproduce this issue
- 方法校验结果被ValidationException吞掉了
Expected Behavior
我希望能够获取到方法校验参数的具体异常信息
Actual Behavior
If there is an exception, please attach the exception trace:
javax.validation.ValidationException: Failed to validate service: com.github.sparkzxl.auth.api.IDictionaryProvider, method: findDictionaryItemMap, cause: [ConstraintViolationImpl{interpolatedMessage='字典类型不能为空', propertyPath=findDictionaryItemMapArgument0, rootBeanClass=class com.github.sparkzxl.auth.api.IDictionaryProvider_FindDictionaryItemMapParameter_java.lang.String_java.util.Set, messageTemplate='字典类型不能为空'}]
观看源码得知ValidationFilter
在进行校验时,会触发JValidator.validate
方法,该方法在2.7.x版本并没有加上try catch,在目前使用的3.0.10版本上进行了try catch,在不影响校验的同时,是否可以把try catch的范围缩小至以下代码之上
if (!violations.isEmpty()) {
logger.info("Failed to validate service: " + clazz.getName() + ", method: " + methodName + ", cause: " + violations);
throw new ConstraintViolationException("Failed to validate service: " + clazz.getName() + ", method: " + methodName + ", cause: " + violations, violations);
}
我希望能够获得ConstraintViolationException异常的信息
It is better to check that ValidationException
is an instance of ConstraintViolationException
. If true, build a custom message for newly created RpcException
.
Could you please create a PR to fix this? Also patch to JValidatorNew
I am glad to create a PR to fix this
现在问题是需要使用ConstraintViolationException的成员变量constraintViolations,还是需要异常类型为ConstraintViolationException?因为前者可能会发生序列化的问题
需要成员变量constraintViolations,得到校验结果,但是会发生序列化问题。
原因就是 ConstraintViolationImpl
会发生序列化问题。我想到的解决办法
- 消费者端引入 ValidationFilter 和 Validation 进行前置校验,非法请求直接在消费者端就拦截掉 (不需要开发 只需要消费者端引入就可以)
- 官方在 Validation 校验发生异常的时候 提供一个可由用户自定义扩展的异常信息包装的处理
如图 可以调用扩展 (通过静态类配置 或者 是spi扩展)对异常信息进行包装,框架提供默认扩展为
new ValidationException(e.getMessage())
即仅返回异常消息,用户可以针对自己的需求,对ConstraintViolation
中的信息进行二次封装成可序列化的类 例如:#10415 这种实现
原因就是
ConstraintViolationImpl
会发生序列化问题。我想到的解决办法
- 消费者端引入 ValidationFilter 和 Validation 进行前置校验,非法请求直接在消费者端就拦截掉 (不需要开发 只需要消费者端引入就可以)
- 官方在 Validation 校验发生异常的时候 提供一个可由用户自定义扩展的异常信息包装的处理
如图 可以调用扩展 (通过静态类配置 或者 是spi扩展)对异常信息进行包装,框架提供默认扩展为
new ValidationException(e.getMessage())
即仅返回异常消息,用户可以针对自己的需求,对ConstraintViolation
中的信息进行二次封装成可序列化的类 例如:The dubbo method parameter validation exception message is swallowed by ValidationException #10415 这种实现
@AlbumenJ @sparkzxl
原因就是
ConstraintViolationImpl
会发生序列化问题。我想到的解决办法
- 消费者端引入 ValidationFilter 和 Validation 进行前置校验,非法请求直接在消费者端就拦截掉 (不需要开发 只需要消费者端引入就可以)
- 官方在 Validation 校验发生异常的时候 提供一个可由用户自定义扩展的异常信息包装的处理
如图 可以调用扩展 (通过静态类配置 或者 是spi扩展)对异常信息进行包装,框架提供默认扩展为
new ValidationException(e.getMessage())
即仅返回异常消息,用户可以针对自己的需求,对ConstraintViolation
中的信息进行二次封装成可序列化的类 例如:The dubbo method parameter validation exception message is swallowed by ValidationException #10415 这种实现
对于 ValidationFilter 的官方实现来说有些太复杂了。
建议自己定义 ValidationFilter 实现,同时通过 dubbo 的 filter 配置关闭官方 Filter,启动自定义 Fitler