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

Extraneous error with an empty string is reported when singleError option is turned on #82

Open
mati-o opened this issue Jan 3, 2021 · 2 comments

Comments

@mati-o
Copy link

mati-o commented Jan 3, 2021

Package Versions:

Tested the following combinations:

Background

Good day, I have observed a strange behavior when using ajv-errors with singleError flag turned on. Honestly, I can't remember why even it was turned on in my code but when I turn it off, this unexpected behavior stops.

The code below is the minimum reproducible example for the issue I am describing. I had a fairly complex schema but I have simplified to the most basic example I could to illustrate the issue.

When I have two errorMessage properties, set as follows - one in the top level and the other in one of the fields, an extraneous empty error is reported.

(In my case there were a lot more).

I hope you'd shed some light on this unexpected behavior. Many thanks!

Code

const AJV = require('ajv').default;
const ajvErrors = require('ajv-errors');

const validator = new AJV({ allErrors: true});

// Add AJV errors with singleError: true
ajvErrors(validator, {
  singleError:true
});

validator.addSchema({
  $id: 'pizzaOrder',
  type:'object',
  additionalProperties: false,
  errorMessage:{
    additionalProperties:'Pizza order is invalid'
  },
  properties:{
    price:{
      type:'number'
    },
    toppings:{
      type:'object',
      additionalProperties: false,
      errorMessage: {
        _: 'Unsupported topping'
      },
      properties: {
        pineapple:{
          type: 'boolean'
        }
      }
    }
  }
});

validator.validate('pizzaOrder', { 
  somethingBad: true, 
  toppings:{
    pineapple:true
  }
});

console.log(JSON.stringify(validator.errors, null, 2));;

Expected Result:

Since I have deliberately put an additionalProperty called somethingBad I would expect it to be reported as follows:

[
  {
    "keyword": "errorMessage",
    "dataPath": "",
    "schemaPath": "#/errorMessage",
    "params": {
      "errors": [
        {
          "keyword": "additionalProperties",
          "dataPath": "",
          "schemaPath": "#/additionalProperties",
          "params": {
            "additionalProperty": "somethingBad"
          },
          "message": "should NOT have additional properties",
          "emUsed": true
        }
      ]
    },
    "message": "Pizza order is invalid"
  }
]

Actual Result:

But actually, as highlighted below, there's an extra error that creeps in with an empty message and empty params.errors for toppings which actually is totally valid.

[
+  {
+   "keyword": "errorMessage",
+    "dataPath": "/toppings",
+    "schemaPath": "#/properties/toppings/errorMessage",
+    "params": {
+      "errors": []
+    },
+    "message": ""
+  },
  {
    "keyword": "errorMessage",
    "dataPath": "",
    "schemaPath": "#/errorMessage",
    "params": {
      "errors": [
        {
          "keyword": "additionalProperties",
          "dataPath": "",
          "schemaPath": "#/additionalProperties",
          "params": {
            "additionalProperty": "somethingBad"
          },
          "message": "should NOT have additional properties",
          "emUsed": true
        }
      ]
    },
    "message": "Pizza order is invalid"
  }
]

Temporal Workarounds:

Currently I have turned of singleError completely, hopefully it won't affect my other schema's error reports

ajvErrors(validator, {
-   singleError:true // removed
});

Another thing I have noticed, which may aid finding the issue is that when I did changed the schema this way:

{
  $id: 'pizzaOrder',
  type:'object',
  additionalProperties: false,
  errorMessage:{
    additionalProperties:'Pizza order is invalid'
  },
  properties:{
    price:{
      type:'number'
    },
    toppings:{
      type:'object',
      additionalProperties: false,
-      errorMessage: {
-       _: 'Unsupported topping'
-      },
+     errorMessage: 'Unsupported topping'
      properties: {
        pineapple:{
          type: 'boolean'
        }
      }
    }
  }
}

The problem went away too. In my case it's not possible however, since I have other error keyword in my full example.

Let me know if any clarifications are required

@epoberezkin
Copy link
Member

Thank you. Am I right that this issue happens in both versions (Ajv v6 and v7), so it’s not a regression?

@mati-o
Copy link
Author

mati-o commented Jan 4, 2021

Yes indeed it happens in both 6 and 7 (with ajv-errors 1 and 2 respectively).

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

2 participants