ajv-validator / ajv-errors

Custom error messages in JSON Schemas for Ajv validator
https://ajv.js.org
MIT License
284 stars 18 forks source link
ajv errors json-schema validator

ajv-errors

Custom error messages in JSON-Schema for Ajv validator

build npm coverage gitter

Please note

ajv-errors v3 supports ajv v8.

If you are using ajv v6, you should use ajv-errors v1

Contents

Install

npm install ajv-errors

Usage

Add the keyword errorMessages to Ajv instance:

const Ajv = require("ajv").default
const ajv = new Ajv({allErrors: true})
// Ajv option allErrors is required
require("ajv-errors")(ajv /*, {singleError: true} */)

See Options below.

Single message

Replace all errors in the current schema and subschemas with a single message:

const schema = {
  type: "object",
  required: ["foo"],
  properties: {
    foo: {type: "integer"},
  },
  additionalProperties: false,
  errorMessage: "should be an object with an integer property foo only",
}

const validate = ajv.compile(schema)
console.log(validate({foo: "a", bar: 2})) // false
console.log(validate.errors) // processed errors

Processed errors:

[
  {
    keyword: "errorMessage",
    message: "should be an object with an integer property foo only",
    // ...
    params: {
      errors: [
        {keyword: "additionalProperties", instancePath: "" /* , ... */},
        {keyword: "type", instancePath: ".foo" /* , ... */},
      ],
    },
  },
]

Messages for keywords

Replace errors for certain keywords in the current schema only:

const schema = {
  type: "object",
  required: ["foo"],
  properties: {
    foo: {type: "integer"},
  },
  additionalProperties: false,
  errorMessage: {
    type: "should be an object", // will not replace internal "type" error for the property "foo"
    required: "should have property foo",
    additionalProperties: "should not have properties other than foo",
  },
}

const validate = ajv.compile(schema)
console.log(validate({foo: "a", bar: 2})) // false
console.log(validate.errors) // processed errors

Processed errors:

[
  {
    // original error
    keyword: type,
    instancePath: "/foo",
    // ...
    message: "should be integer",
  },
  {
    // generated error
    keyword: "errorMessage",
    message: "should not have properties other than foo",
    // ...
    params: {
      errors: [{keyword: "additionalProperties" /* , ... */}],
    },
  },
]

For keywords "required" and "dependencies" it is possible to specify different messages for different properties:

const schema = {
  type: "object",
  required: ["foo", "bar"],
  properties: {
    foo: {type: "integer"},
    bar: {type: "string"},
  },
  errorMessage: {
    type: "should be an object", // will not replace internal "type" error for the property "foo"
    required: {
      foo: 'should have an integer property "foo"',
      bar: 'should have a string property "bar"',
    },
  },
}

Messages for properties and items

Replace errors for properties / items (and deeper), regardless where in schema they were created:

const schema = {
  type: "object",
  required: ["foo", "bar"],
  allOf: [
    {
      properties: {
        foo: {type: "integer", minimum: 2},
        bar: {type: "string", minLength: 2},
      },
      additionalProperties: false,
    },
  ],
  errorMessage: {
    properties: {
      foo: "data.foo should be integer >= 2",
      bar: "data.bar should be string with length >= 2",
    },
  },
}

const validate = ajv.compile(schema)
console.log(validate({foo: 1, bar: "a"})) // false
console.log(validate.errors) // processed errors

Processed errors:

[
  {
    keyword: "errorMessage",
    message: "data.foo should be integer >= 2",
    instancePath: "/foo",
    // ...
    params: {
      errors: [{keyword: "minimum" /* , ... */}],
    },
  },
  {
    keyword: "errorMessage",
    message: "data.bar should be string with length >= 2",
    instancePath: "/bar",
    // ...
    params: {
      errors: [{keyword: "minLength" /* , ... */}],
    },
  },
]

Default message

When the value of keyword errorMessage is an object you can specify a message that will be used if any error appears that is not specified by keywords/properties/items using _ property:

const schema = {
  type: "object",
  required: ["foo", "bar"],
  allOf: [
    {
      properties: {
        foo: {type: "integer", minimum: 2},
        bar: {type: "string", minLength: 2},
      },
      additionalProperties: false,
    },
  ],
  errorMessage: {
    type: "data should be an object",
    properties: {
      foo: "data.foo should be integer >= 2",
      bar: "data.bar should be string with length >= 2",
    },
    _: 'data should have properties "foo" and "bar" only',
  },
}

const validate = ajv.compile(schema)
console.log(validate({})) // false
console.log(validate.errors) // processed errors

Processed errors:

[
  {
    keyword: "errorMessage",
    message: 'data should be an object with properties "foo" and "bar" only',
    instancePath: "",
    // ...
    params: {
      errors: [{keyword: "required" /* , ... */}, {keyword: "required" /* , ... */}],
    },
  },
]

The message in property _ of errorMessage replaces the same errors that would have been replaced if errorMessage were a string.

Templates

Custom error messages used in errorMessage keyword can be templates using JSON-pointers or relative JSON-pointers to data being validated, in which case the value will be interpolated. Also see examples of relative JSON-pointers.

The syntax to interpolate a value is ${<pointer>}.

The values used in messages will be JSON-stringified:

Example:

const schema = {
  type: "object",
  properties: {
    size: {
      type: "number",
      minimum: 4,
    },
  },
  errorMessage: {
    properties: {
      size: "size should be a number bigger or equal to 4, current value is ${/size}",
    },
  },
}

Using property names in error messages

Property names can be used in error messages with the relative JSON-pointer (e.g. 0#).

Example:

const schema = {
  type: "object",
  properties: {
    size: {
      type: "number",
    },
  },
  additionalProperties: {
    not: true,
    errorMessage: “extra property is ${0#}”
  }
}

Options

Defaults:

{
  keepErrors: false,
  singleError: false,
}

Supporters

Roger Kepler

Enterprise support

ajv-errors package is a part of Tidelift enterprise subscription - it provides a centralised commercial support to open-source software users, in addition to the support provided by software maintainers.

Security contact

To report a security vulnerability, please use the Tidelift security contact. Tidelift will coordinate the fix and disclosure. Please do NOT report security vulnerability via GitHub issues.

License

MIT