Режим verbose

Валидация схем JSON в Ajv может работать в нескольких режимах детализации ошибок, и один из ключевых механизмов получения расширенной информации — включение подробного (verbose) режима. Он влияет на структуру объектов ошибок и объём диагностических данных, которые возвращает валидатор при несоответствии данных схеме.

По умолчанию Ajv возвращает компактные объекты ошибок, содержащие минимально необходимую информацию:

  • instancePath — путь к данным, где произошла ошибка
  • schemaPath — путь в схеме
  • keyword — тип нарушения (например, type, required)
  • message — текстовое описание ошибки
  • params — параметры конкретного keyword

Такой формат оптимизирован для производительности и минимизации объёма данных, но часто недостаточен для глубокого анализа сложных схем.

Расширенный (verbose) режим

При включении verbose-режима Ajv добавляет в объект ошибки дополнительные поля, которые позволяют более детально понять контекст нарушения:

  • data — фактическое значение, вызвавшее ошибку
  • schema — часть схемы, которая применялась в момент проверки
  • parentSchema — родительский узел схемы, если он существует
  • расширенные внутренние ссылки на структуру проверки

Эти данные особенно полезны при отладке сложных вложенных схем и динамически формируемых валидаторов.

Активация verbose режима

Включение осуществляется через конфигурацию экземпляра Ajv:

import Ajv from "ajv";

const ajv = new Ajv({
  allErrors: true,
  verbose: true
});

Ключевое значение имеет именно параметр verbose: true, который расширяет состав возвращаемых ошибок.

Пример поведения ошибок

Рассмотрим схему и данные:

const schema = {
  type: "object",
  properties: {
    age: { type: "number" }
  },
  required: ["age"]
};

const data = {
  age: "not-a-number"
};

const validate = ajv.compile(schema);

validate(data);
console.log(validate.errors);

Без verbose

[
  {
    "instancePath": "/age",
    "schemaPath": "#/properties/age/type",
    "keyword": "type",
    "params": {
      "type": "number"
    },
    "message": "must be number"
  }
]

С verbose

[
  {
    "instancePath": "/age",
    "schemaPath": "#/properties/age/type",
    "keyword": "type",
    "params": {
      "type": "number"
    },
    "message": "must be number",
    "data": "not-a-number",
    "schema": "number",
    "parentSchema": {
      "type": "number"
    }
  }
]

Разница заключается в наличии контекстных полей, позволяющих увидеть не только факт ошибки, но и её точное происхождение.

Влияние на производительность

Verbose-режим увеличивает объём памяти, используемый для формирования ошибок, поскольку в структуру включаются дополнительные ссылки на исходные данные и фрагменты схемы. Это может влиять на:

  • скорость валидации при больших массивах данных
  • размер объектов ошибок
  • нагрузку на сборщик мусора

В высоконагруженных системах verbose часто отключают в production-среде, оставляя его для development-режима.

Взаимодействие с allErrors

Параметр allErrors и verbose режим часто используются совместно, но выполняют разные функции:

  • allErrors: true — собирает все ошибки, а не останавливается на первой
  • verbose: true — расширяет информацию внутри каждой ошибки

Комбинация:

const ajv = new Ajv({
  allErrors: true,
  verbose: true
});

даёт максимально детализированный отчёт о валидации, что полезно при тестировании схем.

Применение в отладке схем

Verbose-режим особенно полезен при работе с:

  • вложенными объектами с глубокой структурой
  • сложными комбинациями anyOf, oneOf, allOf
  • динамическими схемами, где структура формируется во время выполнения
  • API-валидацией входящих запросов

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

Поведение с кастомными ключевыми словами

При использовании пользовательских keywords verbose-режим также может расширять контекст ошибок, если разработчик возвращает структурированные данные через errors внутри custom validator’а. В этом случае важно соблюдать согласованность формата, чтобы не смешивать стандартные и пользовательские поля.

Ограничения

Несмотря на полезность расширенного режима, существуют ограничения:

  • невозможность полной сериализации некоторых структур в JSON без потери ссылок
  • увеличение размера логов
  • потенциальная утечка чувствительных данных через поле data, если оно содержит пользовательский ввод
  • усложнение анализа при большом количестве ошибок

В системах, где важна безопасность или минимизация логов, verbose режим требует осторожного использования.

Совместимость с версиями Ajv

Поведение verbose-режима может незначительно отличаться между версиями Ajv:

  • в ранних версиях (v6) структура ошибок была более гибкой и включала больше внутренних полей
  • в современных версиях (v8) акцент сделан на стандартизации формата ошибок JSON Schema Draft 2019-09 / 2020-12

Поэтому при миграции важно учитывать изменение набора доступных полей, особенно если логика приложения опирается на schema или parentSchema.

Использование в системах логирования

Verbose-ошибки часто интегрируются в системы мониторинга и логирования, где требуется:

  • трассировка источника ошибки
  • восстановление контекста запроса
  • диагностика API-ответов

Дополнительные поля позволяют строить более точные отчёты, связывая ошибку с конкретным участком схемы и входными данными.