Skip to content

Commit aef6e9e

Browse files
chaosapeDan DaCosta
andauthored
Quick fix for issue causing the wrong custom message to be used (#634)
Co-authored-by: Dan DaCosta <[email protected]>
1 parent f972484 commit aef6e9e

File tree

6 files changed

+123
-9
lines changed

6 files changed

+123
-9
lines changed

src/main/java/com/networknt/schema/BaseJsonValidator.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public abstract class BaseJsonValidator implements JsonValidator {
3939
protected ValidationContext validationContext;
4040
protected final boolean failFast;
4141
protected final ApplyDefaultsStrategy applyDefaultsStrategy;
42+
private final String customMessage;
4243

4344
public BaseJsonValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema,
4445
ValidatorTypeCode validatorType, ValidationContext validationContext) {
@@ -69,6 +70,11 @@ public BaseJsonValidator(String schemaPath,
6970
this.suppressSubSchemaRetrieval = suppressSubSchemaRetrieval;
7071
this.failFast = failFast;
7172
this.applyDefaultsStrategy = applyDefaultsStrategy != null ? applyDefaultsStrategy : ApplyDefaultsStrategy.EMPTY_APPLY_DEFAULTS_STRATEGY;
73+
if (validatorType != null) {
74+
this.customMessage = validatorType.getCustomMessage();
75+
} else {
76+
this.customMessage = null;
77+
}
7278
}
7379

7480
public String getSchemaPath() {
@@ -137,7 +143,7 @@ protected void parseErrorCode(String errorCodeKey) {
137143
}
138144

139145
protected ValidationMessage buildValidationMessage(String at, String... arguments) {
140-
final ValidationMessage message = ValidationMessage.of(getValidatorType().getValue(), errorMessageType, at, schemaPath, arguments);
146+
final ValidationMessage message = ValidationMessage.ofWithCustom(getValidatorType().getValue(), errorMessageType, customMessage, at, schemaPath, arguments);
141147
if (failFast && !isPartOfOneOfMultipleType()) {
142148
throw new JsonSchemaException(message);
143149
}

src/main/java/com/networknt/schema/JsonSchema.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -282,13 +282,15 @@ private JsonNode getMessageNode(JsonNode schemaNode, JsonSchema parentSchema, St
282282
if (schemaNode.get("message") != null && schemaNode.get("message").get(pname) != null) {
283283
return schemaNode.get("message");
284284
}
285-
JsonNode nodeContainingMessage;
286-
if (parentSchema == null) {
287-
nodeContainingMessage = schemaNode;
288-
} else {
289-
nodeContainingMessage = parentSchema.schemaNode;
285+
JsonNode messageNode;
286+
messageNode = schemaNode.get("message");
287+
if (messageNode == null && parentSchema != null) {
288+
messageNode = parentSchema.schemaNode.get("message");
289+
if (messageNode == null) {
290+
return getMessageNode(parentSchema.schemaNode, parentSchema.getParentSchema(), pname);
291+
}
290292
}
291-
return nodeContainingMessage.get("message");
293+
return messageNode;
292294
}
293295

294296
/************************ START OF VALIDATE METHODS **********************************/

src/main/java/com/networknt/schema/ValidationMessage.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,18 @@ public void setType(String type) {
130130
this.type = type;
131131
}
132132

133-
public static ValidationMessage of(String type, ErrorMessageType errorMessageType, String at, String schemaPath, String... arguments) {
133+
public static ValidationMessage ofWithCustom(String type, ErrorMessageType errorMessageType, String customMessage, String at, String schemaPath, String... arguments) {
134134
ValidationMessage.Builder builder = new ValidationMessage.Builder();
135135
builder.code(errorMessageType.getErrorCode()).path(at).schemaPath(schemaPath).arguments(arguments)
136136
.format(errorMessageType.getMessageFormat()).type(type)
137-
.customMessage(errorMessageType.getCustomMessage());
137+
.customMessage(customMessage);
138138
return builder.build();
139139
}
140140

141+
public static ValidationMessage of(String type, ErrorMessageType errorMessageType, String at, String schemaPath, String... arguments) {
142+
return ofWithCustom(type, errorMessageType, errorMessageType.getCustomMessage(), at, schemaPath, arguments);
143+
}
144+
141145
public static ValidationMessage of(String type, ErrorMessageType errorMessageType, String at, String schemaPath, Map<String, Object> details) {
142146
ValidationMessage.Builder builder = new ValidationMessage.Builder();
143147
builder.code(errorMessageType.getErrorCode()).path(at).schemaPath(schemaPath).details(details)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.networknt.schema;
2+
3+
import com.fasterxml.jackson.databind.JsonNode;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import com.networknt.schema.SpecVersion.VersionFlag;
6+
import java.io.InputStream;
7+
import java.util.HashMap;
8+
import java.util.Map;
9+
import java.util.Set;
10+
import org.junit.jupiter.api.Assertions;
11+
import org.junit.jupiter.api.Test;
12+
13+
public class OverwritingCustomMessageBugTest {
14+
private JsonSchema getJsonSchemaFromStreamContentV7(InputStream schemaContent) {
15+
JsonSchemaFactory factory = JsonSchemaFactory.getInstance(VersionFlag.V7);
16+
return factory.getSchema(schemaContent);
17+
}
18+
19+
private JsonNode getJsonNodeFromStreamContent(InputStream content) throws Exception {
20+
ObjectMapper mapper = new ObjectMapper();
21+
return mapper.readTree(content);
22+
}
23+
24+
@Test
25+
public void customMessageIsNotOverwritten() throws Exception {
26+
Set<ValidationMessage> errors = validate();
27+
Map<String, String> errorMsgMap = transferErrorMsg(errors);
28+
Assertions.assertTrue(errorMsgMap.containsKey("$.toplevel[1].foos"), "error message must contains key: $.foos");
29+
Assertions.assertTrue(errorMsgMap.containsKey("$.toplevel[1].bars"), "error message must contains key: $.bars");
30+
Assertions.assertEquals("{0}: Must be a string with the a shape foofoofoofoo... with at least one foo", errorMsgMap.get("$.toplevel[1].foos"));
31+
Assertions.assertEquals("{0}: Must be a string with the a shape barbarbar... with at least one bar", errorMsgMap.get("$.toplevel[1].bars"));
32+
}
33+
34+
35+
private Set<ValidationMessage> validate() throws Exception {
36+
String schemaPath = "/schema/OverwritingCustomMessageBug.json";
37+
String dataPath = "/data/OverwritingCustomMessageBug.json";
38+
InputStream schemaInputStream = OverwritingCustomMessageBugTest.class.getResourceAsStream(schemaPath);
39+
JsonSchema schema = getJsonSchemaFromStreamContentV7(schemaInputStream);
40+
InputStream dataInputStream = OverwritingCustomMessageBugTest.class.getResourceAsStream(dataPath);
41+
JsonNode node = getJsonNodeFromStreamContent(dataInputStream);
42+
return schema.validate(node);
43+
}
44+
45+
private Map<String, String> transferErrorMsg(Set<ValidationMessage> validationMessages) {
46+
Map<String, String> pathToMessage = new HashMap<>();
47+
validationMessages.forEach(msg -> {
48+
pathToMessage.put(msg.getPath(), msg.getMessage());
49+
});
50+
return pathToMessage;
51+
}
52+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"toplevel": [
3+
{
4+
"foos": "foo",
5+
"Nope": "a",
6+
"bars": "bar"
7+
},
8+
{
9+
"foos": "fee",
10+
"Nope": "b",
11+
"bars": "baz"
12+
},
13+
{
14+
"foos": "foo",
15+
"Nope": "c",
16+
"bars": "bar"
17+
}
18+
]
19+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"type": "object",
3+
"properties": {
4+
"toplevel": {
5+
"type": "array",
6+
"items": {
7+
"type": "object",
8+
"properties": {
9+
"foos": {
10+
"type": "string",
11+
"pattern": "(foo)+",
12+
"message": {
13+
"pattern": "{0}: Must be a string with the a shape foofoofoofoo... with at least one foo"
14+
}
15+
},
16+
"Nope": {
17+
"type": "string"
18+
},
19+
"bars": {
20+
"type": "string",
21+
"pattern": "(bar)+",
22+
"message": {
23+
"pattern": "{0}: Must be a string with the a shape barbarbar... with at least one bar"
24+
}
25+
}
26+
}
27+
},
28+
"minItems": 1
29+
}
30+
}
31+
}

0 commit comments

Comments
 (0)