Ajv пользовательское сообщение об ошибке для типа

Я изучал Ajv с ошибками ajv для проверки схемы JSON и создания пользовательских сообщений об ошибках. все работает на данный момент, но я не могу установить пользовательское сообщение об ошибке для типа для отдельных значений.

const emailSchema = {
 type: 'object',
 required: ['foo', 'bar', 'car'],
 properties: {
  foo: { type: 'integer' },
  bar: { type: 'string' },
  car: { type: 'string' }
 },
 errorMessage: {
  type: 'should be an object',
  required: {
  foo: 'foo field is missing',
  bar: 'bar field is missing',
  car: 'car field is missing'
  }
 } 
};

выводит следующую ошибку

[
    {
        "keyword": "type",
        "dataPath": "/foo",
        "schemaPath": "#/properties/foo/type",
        "params": {
            "type": "integer"
        },
        "message": "should be integer"
    },
    {
        "keyword": "errorMessage",
        "dataPath": "",
        "schemaPath": "#/errorMessage",
        "params": {
            "errors": [
                {
                    "keyword": "required",
                    "dataPath": "",
                    "schemaPath": "#/required",
                    "params": {
                        "missingProperty": "bar"
                    },
                    "message": "should have required property 'bar'"
                }
            ]
        },
        "message": "bar field is missing"
    },
    {
        "keyword": "errorMessage",
        "dataPath": "",
        "schemaPath": "#/errorMessage",
        "params": {
            "errors": [
                {
                    "keyword": "required",
                    "dataPath": "",
                    "schemaPath": "#/required",
                    "params": {
                        "missingProperty": "car"
                    },
                    "message": "should have required property 'car'"
                }
            ]
        },
        "message": "car field is missing"
    }
]

первый объект ошибки с сообщением "должен быть целым числом", могу ли я настроить его так, как будто foo должен быть целым числом. Я ожидаю что-то вроде ниже, но это дает ошибку схемы.

type : {
  foo : "foo must be an Integer"
}

Благодарю.

1 ответ

Вы должны объявить errorMessage в качестве ключевого слова внутри каждого из свойств, смотрите этот пример:

const emailSchema = {
 type: 'object',
 required: ['foo', 'bar', 'car'],
 properties: {
  foo: {
         type: 'integer',
         errorMessage:{ /*In here must be errorMessage not errorMessages*/
                        type: "foo must be an Integer" /* Your Custom Error Message */
                      }
       },
  bar: { type: 'string' },
  car: { type: 'string' }
 },
 errorMessages: { /*Change from errorMessage to errorMessages*/
  type: 'should be an object',
  required: {
    foo: 'foo field is missing',
    bar: 'bar field is missing',
    car: 'car field is missing'
  }
 } 
};

Для случаев использования, когда у нас есть какое-то настраиваемое сообщение об ошибке или любые другие данные, мы должны использовать путь к схеме. Когда мы получаем ошибку проверки, мы также получаем error.keyword в моем случае у меня была дополнительная проверка в блоке if и else, как показано ниже

schema.allOf= Object.keys(bankCodes).map((key: any) => ({
    if: {
      properties: {
        routingCodeType1: { const: bankCodes[key].code },
      },
    },
    then: {
      properties: {
        routingCodeValue1: {
          pattern: bankCodes[key].pattern, //<-- this was cause of validation fail
          errorMessage: bankCodes[key].errorMessage,
        },
      },
    },
  }))

так что в error.keyword я бы получил pattern так же как schemaPath=/#/allOf/2/then/properties/routingCodeValue1/pattern

так что в основном мне пришлось бы использовать этот путь к схеме для извлечения связанных данных из схемы. Следующий код помог мне с этим

const getPatternMessage = (error: any, schema: any) => {
  if (error.keyword === 'pattern') {
    const fieldName = error.dataPath.substring(1); // routingCodeValue1
    const keyArr = error.schemaPath.split('/'); // ['#','allOf','2'..,'pattern']
    keyArr.pop(); // remove '#'
    keyArr.shift(); // remove 'pattern'
    const prop = keyArr.reduce((acc, key) => acc[key], schema);
/** 
prop contains  {
          pattern: '^[a-z]{9}$',
          errorMessage:'routingCodeValue1 should be 9 characters'
        },
*/
    return {
      [fieldName]: prop.errorMessage,
    };
  }
};

Таким образом мы можем извлечь пользовательское сообщение об ошибке или любые другие данные, которые нам нужны.

Суть заключается в использовании свойства schemaPath

Другие вопросы по тегам