-
Notifications
You must be signed in to change notification settings - Fork 544
feat(schema): support custom error message definition, for issue #1559 #3904
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements support for custom error messages in JSON schema validation, addressing issue #1559. The implementation uses the Template Method pattern to intercept validation results and replace error messages when a custom message is defined.
Key changes:
- Refactored all
validate()methods tovalidateInternal()in schema implementations - Added wrapper
validate()methods in the baseJSONSchemaclass that apply custom error messages - Added support for both
errorMessageandmessageproperties in schema definitions
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| JSONSchema.java | Added customErrorMessage field and refactored validation to use Template Method pattern with wrapper methods |
| IntegerSchema.java | Renamed validate() methods to validateInternal() to support custom error message interception |
| NumberSchema.java | Renamed validate() methods to validateInternal() to support custom error message interception |
| StringSchema.java | Renamed validate() method to validateInternal() to support custom error message interception |
| ObjectSchema.java | Renamed validate() method to validateInternal() to support custom error message interception |
| ArraySchema.java | Renamed validate() method to validateInternal() to support custom error message interception |
| BooleanSchema.java | Renamed validate() method to validateInternal() to support custom error message interception |
| EnumSchema.java | Renamed validate() method to validateInternal() to support custom error message interception |
| NullSchema.java | Renamed validate() method to validateInternal() to support custom error message interception |
| AllOf.java | Renamed validate() method to validateInternal() to support custom error message interception |
| AnyOf.java | Renamed validate() method to validateInternal() to support custom error message interception |
| OneOf.java | Renamed validate() method to validateInternal() to support custom error message interception |
| Not.java | Renamed validate() method to validateInternal() to support custom error message interception |
| Any.java | Renamed validate() method to validateInternal() to support custom error message interception |
| UnresolvedReference.java | Renamed validate() method to validateInternal() to support custom error message interception |
| CustomErrorMessageTest.java | Added comprehensive test coverage for custom error messages including integer validation, string patterns, nested objects, and annotation-based schemas |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @Test | ||
| public void testAnnotationSchemaMessage() { | ||
| String json = "{\"age\": 5}"; | ||
| try { | ||
| JSON.parseObject(json, User.class); | ||
| } catch (JSONSchemaValidException e) { | ||
| Assertions.assertEquals("Age too young", e.getMessage()); | ||
| } | ||
| } |
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test expects an exception to be thrown but does not assert that it was actually thrown. If no exception occurs, the test will silently pass. Add an assertion after the try-catch block to fail the test if the expected exception was not thrown.
|
|
||
| public ValidateResult validate(Long value) { | ||
| return validate((Object) value); | ||
| public final ValidateResult validate(Float value) { |
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method JSONSchema.validate(..) could be confused with overloaded method validate, since dispatch depends on static types.
|
|
||
| public ValidateResult validate(Integer value) { | ||
| return validate((Object) value); | ||
| protected ValidateResult validateInternal(Float value) { |
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method JSONSchema.validateInternal(..) could be confused with overloaded method validateInternal, since dispatch depends on static types.
|
|
||
| public ValidateResult validate(Double value) { | ||
| return validate((Object) value); | ||
| public final ValidateResult validate(Long value) { |
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
|
||
| public ValidateResult validate(Float value) { | ||
| return validate((Object) value); | ||
| protected ValidateResult validateInternal(Long value) { |
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method JSONSchema.validateInternal(..) could be confused with overloaded method validateInternal, since dispatch depends on static types.
Method JSONSchema.validateInternal(..) could be confused with overloaded method validateInternal, since dispatch depends on static types.
| return validateInternal((Object) value); | ||
| } | ||
|
|
||
| public final ValidateResult validate(Double value) { |
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method JSONSchema.validate(..) could be confused with overloaded method validate, since dispatch depends on static types.
| protected ValidateResult validateInternal(Double value) { | ||
| return validateInternal((Object) value); | ||
| } | ||
|
|
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method JSONSchema.validateInternal(..) could be confused with overloaded method validateInternal, since dispatch depends on static types.
| protected ValidateResult validateInternal(Double value) { | |
| return validateInternal((Object) value); | |
| } |
| return validateInternal((Object) value); | ||
| } | ||
|
|
||
| public final ValidateResult validate(double value) { |
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method JSONSchema.validate(..) could be confused with overloaded method validate, since dispatch depends on static types.
| protected ValidateResult validateInternal(long value) { | ||
| return validateInternal((Object) value); | ||
| } | ||
|
|
||
| public final ValidateResult validate(long value) { | ||
| ValidateResult result = validateInternal(value); | ||
| if (!result.isSuccess() && customErrorMessage != null) { | ||
| return new ValidateResult(false, customErrorMessage); | ||
| } | ||
| return result; | ||
| } | ||
| protected ValidateResult validateInternal(double value) { | ||
| return validateInternal((Object) value); | ||
| } | ||
|
|
||
| public final ValidateResult validate(double value) { | ||
| ValidateResult result = validateInternal(value); | ||
| if (!result.isSuccess() && customErrorMessage != null) { | ||
| return new ValidateResult(false, customErrorMessage); | ||
| } | ||
| return result; | ||
| } | ||
|
|
||
| protected ValidateResult validateInternal(Double value) { | ||
| return validateInternal((Object) value); | ||
| } | ||
|
|
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method JSONSchema.validateInternal(..) could be confused with overloaded method validateInternal, since dispatch depends on static types.
| protected ValidateResult validateInternal(long value) { | |
| return validateInternal((Object) value); | |
| } | |
| public final ValidateResult validate(long value) { | |
| ValidateResult result = validateInternal(value); | |
| if (!result.isSuccess() && customErrorMessage != null) { | |
| return new ValidateResult(false, customErrorMessage); | |
| } | |
| return result; | |
| } | |
| protected ValidateResult validateInternal(double value) { | |
| return validateInternal((Object) value); | |
| } | |
| public final ValidateResult validate(double value) { | |
| ValidateResult result = validateInternal(value); | |
| if (!result.isSuccess() && customErrorMessage != null) { | |
| return new ValidateResult(false, customErrorMessage); | |
| } | |
| return result; | |
| } | |
| protected ValidateResult validateInternal(Double value) { | |
| return validateInternal((Object) value); | |
| } | |
| public final ValidateResult validate(long value) { | |
| ValidateResult result = validateInternal((Object) value); | |
| if (!result.isSuccess() && customErrorMessage != null) { | |
| return new ValidateResult(false, customErrorMessage); | |
| } | |
| return result; | |
| } | |
| public final ValidateResult validate(double value) { | |
| ValidateResult result = validateInternal((Object) value); | |
| if (!result.isSuccess() && customErrorMessage != null) { | |
| return new ValidateResult(false, customErrorMessage); | |
| } | |
| return result; | |
| } |
| public abstract ValidateResult validate(Object value); | ||
| protected abstract ValidateResult validateInternal(Object value); | ||
|
|
||
| public final ValidateResult validate(Object value) { |
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method JSONSchema.validate(..) could be confused with overloaded method ObjectSchema.validate, since dispatch depends on static types.
|
errorMessage字段太长了,是不是可以用error就可以了? |
好的,我加一下 |
What this PR does / why we need it?
Summary of your change
Please indicate you've done the following: