dubbo icon indicating copy to clipboard operation
dubbo copied to clipboard

The dubbo method parameter validation exception message is swallowed by ValidationException

Open zhouxinlei828 opened this issue 2 years ago • 7 comments

  • [ ] 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

  1. 方法校验结果被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='字典类型不能为空'}]

image

观看源码得知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);
            }

image

我希望能够获得ConstraintViolationException异常的信息

zhouxinlei828 avatar Aug 08 '22 06:08 zhouxinlei828

It is better to check that ValidationException is an instance of ConstraintViolationException. If true, build a custom message for newly created RpcException.

AlbumenJ avatar Aug 09 '22 03:08 AlbumenJ

Could you please create a PR to fix this? Also patch to JValidatorNew

AlbumenJ avatar Aug 09 '22 03:08 AlbumenJ

I am glad to create a PR to fix this

zhouxinlei828 avatar Aug 09 '22 08:08 zhouxinlei828

image

现在问题是需要使用ConstraintViolationException的成员变量constraintViolations,还是需要异常类型为ConstraintViolationException?因为前者可能会发生序列化的问题

chenziqiang666 avatar Aug 11 '22 09:08 chenziqiang666

需要成员变量constraintViolations,得到校验结果,但是会发生序列化问题。

zhouxinlei828 avatar Aug 11 '22 09:08 zhouxinlei828

原因就是 ConstraintViolationImpl 会发生序列化问题。我想到的解决办法

  1. 消费者端引入 ValidationFilter 和 Validation 进行前置校验,非法请求直接在消费者端就拦截掉 (不需要开发 只需要消费者端引入就可以)
  2. 官方在 Validation 校验发生异常的时候 提供一个可由用户自定义扩展的异常信息包装的处理 image 如图 可以调用扩展 (通过静态类配置 或者 是spi扩展)对异常信息进行包装,框架提供默认扩展为 new ValidationException(e.getMessage()) 即仅返回异常消息,用户可以针对自己的需求,对ConstraintViolation 中的信息进行二次封装成可序列化的类 例如:#10415 这种实现

liufeiyu1002 avatar Aug 12 '22 16:08 liufeiyu1002

原因就是 ConstraintViolationImpl 会发生序列化问题。我想到的解决办法

  1. 消费者端引入 ValidationFilter 和 Validation 进行前置校验,非法请求直接在消费者端就拦截掉 (不需要开发 只需要消费者端引入就可以)
  2. 官方在 Validation 校验发生异常的时候 提供一个可由用户自定义扩展的异常信息包装的处理 image 如图 可以调用扩展 (通过静态类配置 或者 是spi扩展)对异常信息进行包装,框架提供默认扩展为 new ValidationException(e.getMessage()) 即仅返回异常消息,用户可以针对自己的需求,对ConstraintViolation 中的信息进行二次封装成可序列化的类 例如:The dubbo method parameter validation exception message is swallowed by ValidationException #10415 这种实现

@AlbumenJ @sparkzxl

liufeiyu1002 avatar Aug 12 '22 16:08 liufeiyu1002

原因就是 ConstraintViolationImpl 会发生序列化问题。我想到的解决办法

  1. 消费者端引入 ValidationFilter 和 Validation 进行前置校验,非法请求直接在消费者端就拦截掉 (不需要开发 只需要消费者端引入就可以)
  2. 官方在 Validation 校验发生异常的时候 提供一个可由用户自定义扩展的异常信息包装的处理 image 如图 可以调用扩展 (通过静态类配置 或者 是spi扩展)对异常信息进行包装,框架提供默认扩展为 new ValidationException(e.getMessage()) 即仅返回异常消息,用户可以针对自己的需求,对ConstraintViolation 中的信息进行二次封装成可序列化的类 例如:The dubbo method parameter validation exception message is swallowed by ValidationException #10415 这种实现

对于 ValidationFilter 的官方实现来说有些太复杂了。

建议自己定义 ValidationFilter 实现,同时通过 dubbo 的 filter 配置关闭官方 Filter,启动自定义 Fitler

chickenlj avatar Sep 02 '22 02:09 chickenlj