natesilva / jayschema

[Unmaintained] - A comprehensive JSON Schema validator for Node.js
BSD 3-Clause "New" or "Revised" License
217 stars 22 forks source link

Error message is not clear in the case of "oneOf" usage #30

Closed mlito closed 10 years ago

mlito commented 10 years ago

Hello When using schema with "oneOf" part , The error message is not clear. Here is the shema :

{ "oneOf": [ { "$ref": "#/definitions/illegal" }, { "$ref": "#/definitions/legal" } ], "definitions": { "illegal": { "type": "object", "properties": { "propiska": { "type": "string", "enum": [ "no" ] }, "firstName": { "type": "string" }, "lastName": { "type": "string" }, "age": { "description": "Age in years", "type": "integer", "minimum": 0 } }, "required": [ "firstName", "lastName", "propiska" ] }, "legal": { "type": "object", "properties": { "propiska": { "type": "string", "enum": [ "yes" ] }, "firstName": { "type": "string" }, "lastName": { "type": "string" }, "age": { "description": "Age in years", "type": "integer", "minimum": 0 }, "address": { "type": "object", "properties": { "street": { "type": "string" }, "city": { "type": "string" } }, "required": [ "city" ] } }, "required": [ "firstName", "lastName", "address", "propiska" ] } } }

And here is instance , which fails in validation because required "firstName" property is missing
{ "firstName111":"kkkk",
"lastName":"llll", "age1111": 30, "address":{ "street":"Pall Mall", "city":"London" }, "propiska":"yes" }

Here is code for validation :

console.log('synchronous result:', js.validate(instance, schema));

Here is validation result :

synchronous result: [ { instanceContext: '#', resolutionScope: 'anon-schema://3699577afc51054fe9c66a9fb18d75dc7f692a89/#', constraintName: 'oneOf', constraintValue: [ [Object], [Object] ], desc: 'does not validate against any of these schemas; must validate against one and only one of them', kind: 'SubSchemaValidationError', subSchemaValidationErrors: { '#/definitions/illegal': [Object], '#/definitions/legal': [Object] } } ]

From the error message above is not clear , what is exact error. In the case of simple schema (without usage "oneOf") error message :

synchronous result: [ { instanceContext: '#', resolutionScope: 'anon-schema://ad55c1b70fa6557316d3b19574bcab746e90a426/#', constraintName: 'required', constraintValue: [ 'firstName', 'lastName', 'address', 'propiska' ], desc: 'missing: firstName', kind: 'ObjectValidationError' } ]

seems better. The question is : is there something in the code when using schema with "oneOf"? Thanks in advance

natesilva commented 10 years ago

You can make it show the complete error details (not just [Object]) by using util.inspect like this:

var util = require('util');
var errs = js.validate(instance, schema);
console.log('synchronous result:', util.inspect(errs, {depth: null}));

Result:

synchronous result: [ { instanceContext: '#',
    resolutionScope: 'anon-schema://3699577afc51054fe9c66a9fb18d75dc7f692a89/#',
    constraintName: 'oneOf',
    constraintValue: 
     [ { '$ref': '#/definitions/illegal' },
       { '$ref': '#/definitions/legal' } ],
    desc: 'does not validate against any of these schemas; must validate against one and only one of them',
    kind: 'SubSchemaValidationError',
    subSchemaValidationErrors: 
     { '#/definitions/illegal': 
        [ { instanceContext: '#',
            resolutionScope: 'anon-schema://3699577afc51054fe9c66a9fb18d75dc7f692a89/#/definitions/illegal',
            constraintName: 'required',
            constraintValue: [ 'firstName', 'lastName', 'propiska' ],
            desc: 'missing: firstName',
            kind: 'ObjectValidationError' },
          { instanceContext: '#/propiska',
            resolutionScope: 'anon-schema://3699577afc51054fe9c66a9fb18d75dc7f692a89/#/definitions/illegal/properties/propiska',
            constraintName: 'enum',
            constraintValue: [ 'no' ],
            testedValue: 'yes' } ],
       '#/definitions/legal': 
        [ { instanceContext: '#',
            resolutionScope: 'anon-schema://3699577afc51054fe9c66a9fb18d75dc7f692a89/#/definitions/legal',
            constraintName: 'required',
            constraintValue: [ 'firstName', 'lastName', 'address', 'propiska' ],
            desc: 'missing: firstName',
            kind: 'ObjectValidationError' } ] } } ]

This is showing you that the instance did not match the oneOf constraint, and for each of the schemas reference by the oneOf keyword, it shows you the corresponding validation failure.