java-json-tools / json-schema-validator

A JSON Schema validation implementation in pure Java, which aims for correctness and performance, in that order
http://json-schema-validator.herokuapp.com/
Other
1.63k stars 399 forks source link

json-schema-validator error messages are not descriptive #183

Open aabdelaziz opened 8 years ago

aabdelaziz commented 8 years ago

I have tried to make use of:

json-schema-validator but I found that it is only good when validating a well formed Json request, and there are only errors at root level at that point it will generate readable error messages so if you sent empty request while two properties were expected as follows

{"CreateStudentRequest":{}}

it will generate the following error

object has missing required properties (["Student","StudentPublicKey"])

but if you make any kind of mistake like extra comma


{
    "CreateStudentRequest": {   
        "StudentPublicKey":"30820122300D06",
    }
}

it would raise jackson parser error as follows

com.fasterxml.jackson.core.JsonParseException: Unexpected character ('}' (code 125)): was expecting double-quote to start field name at [Source: java.io.StringReader@5a24fc4a; line: 3, column: 2] and if a good Json request is sent (in terms of Jackson parser) but was missing some elements not at root level something like


{
    "CreateStudentRequest": {
        "Student": {
            "DomainName": "abc.com",
            "EmailAddress": "student-01@abc.com"
        },
        "StudentPublicKey": "30820122300D06"
    }
}

it would generate the following error because of missing Student.StudentName and Student.StudentId


    instance failed to match all required schemas (matched only 0 out of 1)

    instance failed to match all required schemas (matched only 0 out of 1)

why I'm sure that my issue in the validator and not in my Json-Schema because there is an online jsone schema validator that do exactly what I'm expecting when I provide my json-schema and my json request it generates somthing like


Found 6 error(s)

Message: JSON does not match all schemas from 'allOf'. Invalid schema indexes: 0. Schema path: #/definitions/CreateStudentRequest/properties/Student/allOf

Message: Required properties are missing from object: StudentName, DomainName, StudentId. Schema path: #/definitions/CreateStudentRequest/properties/Student/allOf/0/required

Message: JSON does not match all schemas from 'allOf'. Invalid schema indexes: 0. Schema path: #/definitions/CreateStudentRequest/properties/StudentPublicKey/allOf

Message: JSON does not match any schemas from 'anyOf'. Schema path: #/definitions/hexBinary/anyOf

Message: Invalid type. Expected Null but got String. Schema path: #/definitions/hexBinary/anyOf/1/type

Message: Invalid type. Expected Array but got String. Schema path: #/definitions/hexBinary/anyOf/0/type

So Is there a way to get much more good error messages from json-schema-validator

nickawatts commented 8 years ago

On your first question regarding syntactically incorrect JSON input, that is, by definition, invalid JSON. In other words, you don't need a schema to determine that the syntax of a JSON string is invalid. Your code should probably catch any exceptions that are thrown while deserializing the JSON and respond to them appropriately. Only when you've successfully deserialized the JSON should you attempt to validate against a schema.

On your second question, you can tell the schema validator to do a ["deep check"](http://fge.github.io/json-schema-validator/2.2.x/com/github/fge/jsonschema/main/JsonSchema.html#validate%28com.fasterxml.jackson.databind.JsonNode, boolean%29) by using the two argument JsonSchema.validate method.

So doing something like this:

final JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
final JsonSchema schema = factory.getJsonSchema(jsonSchema);
ProcessingReport report = schema.validate(jsonInput, true);
System.out.println(report);

will produce a report object that contains all of the errors found, not just the first one.

Also, your second question was also answered in comment #180.

aabdelaziz commented 8 years ago

Thanks Nickawatts for your reply, Regarding first point that the extra comma is syntactically incorrect; I think this is not the case for all json parsers (org.json parser or the parser behind http://www.jsonschemavalidator.net/) however it is the case for jackson parser. and I don't want to deserialize the json request as it will be deserialized later by the requested API here I have an interceptor with a main target to validate the json request against the schema if it is ok the api will recieve the request and deserialze it ... else it should raise validation errors with all found problems.

for the "deep check" I changed my code to be exactly as you specified but this change nothing as I provided request with two missing properties it generates

instance failed to match all required schemas (matched only 0 out of 1)
instance failed to match all required schemas (matched only 0 out of 1)

so it sounds like the deep checking was enabled by default at my side, my probelm is that I need a meaningful error message instead of the "instance failed to match all required schemas (matched only 0 out of 1)"

kellyfj commented 8 years ago

I agree it would be a wonderful addition if the schema path to the offending part of the JSON document could be added to the message

aliveni commented 6 years ago

Is this issue resolved? If not, is there any alternative?

reitzig commented 6 years ago

I also stumbled over this.

I get

instance failed to match exactly one schema (matched 3 out of 3)

but it doesn't tell me where, or which JSON fragment failed to validate against which (sub)schema.

Compare with the output of Ruby's json-schema for inspiration.