Skip to content
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

Default error message does not produce consistent output for oneOf nested in an array (expect 1 errors in output) #83

Open
typhonrt opened this issue Jan 28, 2021 · 0 comments

Comments

@typhonrt
Copy link

ajv@7.0.3
ajv-errors@2.0.0

Greets,

I have included schema and simple test case below showing that a default error message does not produce consistent results. For some reason the "nested" oneOf statement w/ default error message produces two entries in the errors output. The oneOf statement at the top level which is exactly the same produces one entry in the errors output.

IE for the schema below the entry count with the default error message should be the same for both failing validation cases:

{ system: [false] } and { packs: [{ system: [false] }] }

The latter is not picking up the child items type error in the default error message which is part of the oneOf block.

const Ajv = require("ajv").default;
const ajv = new Ajv({ allErrors: true });

// Ajv option allErrors is required
require("ajv-errors")(ajv);

const schema = {
   $id: "test",
   $schema: "http://json-schema.org/draft-07/schema#",
   type: "object",
   properties: {
      packs: {
         type: "array",
         items: {
            type: "object",
            properties: {
               system: {
                  oneOf: [
                     { type: "string" },
                     {
                        items: { type: "string" },
                        type: "array"
                     }
                  ],
                  errorMessage: "should be a string or array of strings"
               }
            }
         }
      },
      system: {
         oneOf: [
            { type: "string" },
            {
               items: { type: "string" },
               type: "array"
            }
         ],
         errorMessage: "should be a string or array of strings"
      }
   }
};


const validate = ajv.compile(schema);

// Expect `errorMessage` to catch all errors at or below the oneOf level.
console.log(`{ system: [false] }:`);
console.log(JSON.stringify(validate.errors, null, 3));

// Expect `errorMessage` to catch all errors at or below the oneOf level.
// However it does not catch the further items type and there are two errors.
console.log('\n-------------------------------------------------------------\n');
console.log(`expect only one error in 'errors', but there are two for { packs: [{ system: [false] }] }:`);
console.log(JSON.stringify(validate.errors, null, 3));

#Output:

{ system: [false] }:
[
   {
      "keyword": "errorMessage",
      "dataPath": "/system",
      "schemaPath": "#/properties/system/errorMessage",
      "params": {
         "errors": [
            {
               "keyword": "type",
               "dataPath": "/system",
               "schemaPath": "#/properties/system/oneOf/0/type",
               "params": {
                  "type": "string"
               },
               "message": "should be string",
               "emUsed": true
            },
            {
               "keyword": "type",
               "dataPath": "/system/0",
               "schemaPath": "#/properties/system/oneOf/1/items/type",
               "params": {
                  "type": "string"
               },
               "message": "should be string",
               "emUsed": true
            },
            {
               "keyword": "oneOf",
               "dataPath": "/system",
               "schemaPath": "#/properties/system/oneOf",
               "params": {
                  "passingSchemas": null
               },
               "message": "should match exactly one schema in oneOf",
               "emUsed": true
            }
         ]
      },
      "message": "should be a string or array of strings"
   }
]

-------------------------------------------------------------

expect only one error in 'errors', but there are two for { packs: [{ system: [false] }] }:
[
   {
      "keyword": "type",
      "dataPath": "/packs/0/system/0",
      "schemaPath": "#/properties/packs/items/properties/system/oneOf/1/items/type",
      "params": {
         "type": "string"
      },
      "message": "should be string"
   },
   {
      "keyword": "errorMessage",
      "dataPath": "/packs/0/system",
      "schemaPath": "#/properties/packs/items/properties/system/errorMessage",
      "params": {
         "errors": [
            {
               "keyword": "type",
               "dataPath": "/packs/0/system",
               "schemaPath": "#/properties/packs/items/properties/system/oneOf/0/type",
               "params": {
                  "type": "string"
               },
               "message": "should be string",
               "emUsed": true
            },
            {
               "keyword": "oneOf",
               "dataPath": "/packs/0/system",
               "schemaPath": "#/properties/packs/items/properties/system/oneOf",
               "params": {
                  "passingSchemas": null
               },
               "message": "should match exactly one schema in oneOf",
               "emUsed": true
            }
         ]
      },
      "message": "should be a string or array of strings"
   }
]
typhonrt added a commit to typhonjs-fvtt-lib/validate-manifest that referenced this issue Jan 28, 2021
typhonrt added a commit to typhonjs-fvtt-lib/validate-manifest that referenced this issue Jan 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant