Skip to content

KAFKA-4709:Error message from Struct.validate() should include the name of the offending field.#2521

Closed
Aegeaner wants to merge 6 commits intoapache:trunkfrom
Aegeaner:KAFKA-4709
Closed

KAFKA-4709:Error message from Struct.validate() should include the name of the offending field.#2521
Aegeaner wants to merge 6 commits intoapache:trunkfrom
Aegeaner:KAFKA-4709

Conversation

@Aegeaner
Copy link
Copy Markdown
Contributor

@Aegeaner Aegeaner commented Feb 9, 2017

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 9, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.12/1583/
Test FAILed (JDK 8 and Scala 2.12).

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 9, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.11/1586/
Test FAILed (JDK 8 and Scala 2.11).

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 9, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk7-scala2.10/1583/
Test FAILed (JDK 7 and Scala 2.10).

try {
ConnectSchema.validateValue(fieldSchema, value);
} catch(DataException e) {
throw new DataException("Invalid value: null used for required field: " + field.name() + ", schema type: " + fieldSchema.type());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While current implementation of validateValue only throws DataException when a required field has null value, in general we may have other exception in the future, right? Then it may be misleading to claim that "null used for required field" here. Maybe you can do throw new DataException(..., e) here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I will keep the original exception message and add some additional field info on it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 13, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.12/1651/
Test FAILed (JDK 8 and Scala 2.12).

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 13, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.11/1654/
Test FAILed (JDK 8 and Scala 2.11).

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 13, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk7-scala2.10/1651/
Test FAILed (JDK 7 and Scala 2.10).

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 13, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.12/1652/
Test FAILed (JDK 8 and Scala 2.12).

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 13, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.11/1655/
Test FAILed (JDK 8 and Scala 2.11).

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 13, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk7-scala2.10/1652/
Test FAILed (JDK 7 and Scala 2.10).

try {
ConnectSchema.validateValue(fieldSchema, value);
} catch(DataException e) {
throw new DataException("Validate failed for required field: \"" + field.name() + "\", "
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strictly speaking you don't know whether this is a required field here. Also, you probably don't need to print e.getMessage() again since the exception have already included this message by including e in the newly constructed exception.

Actually, if all you need is the field name, would it be simpler to just keep the Struct.java as it is, and change ConnectSchema.java to do throw new DataException("Invalid value: null used for required field " + schema.name())

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is also my first intuition here, but schema.name() returns null here. And also, schema name is not field name.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throwing new DataException(..., e) doesnet include original exception message, but only set up original exception as the cause in new exception. @lindong28

Copy link
Copy Markdown
Member

@lindong28 lindong28 Feb 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Aegeaner Yeah the original exception message is included as cause and will be printed to the log or console when the exception is thrown. That is why I think the 2nd exception includes the original exception message. I thought this is enough for user.

Also, I see your point that schema.name() is null. Would it be more precise to remove required from the 2nd exception message? Another alternative is to include an identifier (e.g. schema field name) as a parameter to validateValue(...) so that this method can identify the field with problem in the exception message. Doing this allows us to identify the field in all scenarios where validateValue(...) failed. But this also requires more change so you may want to do this only if a committer suggested so.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lindong28 yeah validateValue(..) method is more primitive so not that easy to change

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 13, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.12/1654/
Test FAILed (JDK 8 and Scala 2.12).

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 13, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.11/1657/
Test FAILed (JDK 8 and Scala 2.11).

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 13, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk7-scala2.10/1654/
Test FAILed (JDK 7 and Scala 2.10).

@guozhangwang
Copy link
Copy Markdown
Contributor

@Aegeaner @lindong28 I'd suggest change the signature of validateValue to take Field and Object as the parameter. BTW is this a public API? cc @ewencp

@Aegeaner
Copy link
Copy Markdown
Contributor Author

@guozhangwang It's not a public API but is used quite often in connect schema tests. Kafka Connect exposed REST api to validate configs.

@guozhangwang
Copy link
Copy Markdown
Contributor

@Aegeaner I understand. If possible we an just change its usage in all the unit test as well.

@lindong28
Copy link
Copy Markdown
Member

@guozhangwang @Aegeaner I am not sure if we can simply change the method signature to be validateValue(Field field, Object value). Suppose schema.type is ARRAY and validateValue(...) calls itself recursively, what should be the value of field? What if schema.type is MAP? Maybe we should just add a method with signature validateValue(String name, Schema schema, Object value). The code change would be much smaller with this approach. The existing validateValue(Schema schema, Object value) can just call validateValue(null, schema, value) so that we don't have to touch unit tests.

@guozhangwang
Copy link
Copy Markdown
Contributor

@lindong28 Sounds good to me.

@Aegeaner
Copy link
Copy Markdown
Contributor Author

@lindong28 @guozhangwang Thanks for your advice. I have changed validateValue(..) signature to pass the field name.

if (value == null) {
if (!schema.isOptional())
throw new DataException("Invalid value: null used for required field");
throw new DataException("Invalid value null used for required field: \"" + name
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nits: not sure if we should : after Invalid value in the error message. Otherwise LGTM.

Thanks for the update.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lindong28 Thanks, I have added field info to all DataException message in validateValue(..).

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 15, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.11/1691/
Test PASSed (JDK 8 and Scala 2.11).

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 15, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.12/1688/
Test FAILed (JDK 8 and Scala 2.12).

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 15, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk7-scala2.10/1688/
Test FAILed (JDK 7 and Scala 2.10).

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 15, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.11/1692/
Test FAILed (JDK 8 and Scala 2.11).

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 15, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.12/1689/
Test FAILed (JDK 8 and Scala 2.12).

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 15, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk7-scala2.10/1689/
Test FAILed (JDK 7 and Scala 2.10).


if (expectedClasses == null)
throw new DataException("Invalid Java object for schema type " + schema.type() + ": " + value.getClass());
throw new DataException("Invalid Java object for schema type " + schema.type()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message is updated to say "required field". Do we actually know that this is a required field here?

}
if (!foundMatch)
throw new DataException("Invalid Java object for schema type " + schema.type() + ": " + value.getClass());
throw new DataException("Invalid Java object for schema type " + schema.type()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message is updated to say "required field". Do we actually know that this is a required field here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed "required" from error message. we can judge if it's required field from schema.isOptional() , but we may don't care about it when the value is not null.

@guozhangwang
Copy link
Copy Markdown
Contributor

Added FakeSchema does not have apache header, hence the checkstyle error:

scala2.12/connect/api/src/test/java/org/apache/kafka/connect/data/FakeSchema.java:1: Line does not match expected header line of '/\*\*'.
 FAILED

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 16, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.11/1704/
Test PASSed (JDK 8 and Scala 2.11).

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 16, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk7-scala2.10/1701/
Test PASSed (JDK 7 and Scala 2.10).

@asfbot
Copy link
Copy Markdown

asfbot commented Feb 16, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.12/1701/
Test FAILed (JDK 8 and Scala 2.12).

@guozhangwang
Copy link
Copy Markdown
Contributor

looks good to me overall. @lindong28 do you want to take another look?

@lindong28
Copy link
Copy Markdown
Member

@guozhangwang @Aegeaner Thank you. LGTM.

@asfgit asfgit closed this in 6c83939 Feb 16, 2017
@guozhangwang
Copy link
Copy Markdown
Contributor

Merged to trunk.

hachikuji pushed a commit to confluentinc/kafka that referenced this pull request Feb 23, 2017
…me of the offending field.

https://issues.apache.org/jira/browse/KAFKA-4709

Author: Aegeaner <xihuke@gmail.com>

Reviewers: Dong Lin, Guozhang Wang

Closes apache#2521 from Aegeaner/KAFKA-4709
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants