Объект ValidationError

ValidationError в библиотеке class-validator представляет собой основной объект, через который система валидации возвращает информацию о найденных нарушениях правил. Каждый экземпляр описывает конкретную ошибку, привязанную к определённому свойству объекта, и может быть частью иерархического дерева при работе со вложенными структурами данных.

Каждый ValidationError содержит набор полей, отражающих контекст ошибки и её происхождение внутри проверяемого объекта.

target

Содержит исходный объект, который проходил валидацию.

  • Тип: object
  • Назначение: ссылка на экземпляр DTO или простого объекта, в котором обнаружена ошибка

Особенность: Поле сохраняет полный объект, даже если ошибка относится только к одному свойству, что позволяет восстановить контекст валидации.


property

Определяет имя свойства, в котором обнаружено нарушение.

  • Тип: string
  • Пример: "email", "password", "profile.age"

Поведение в иерархии: При вложенной валидации значение может отражать путь к полю только на текущем уровне, тогда как полная структура формируется через цепочку children.


value

Содержит фактическое значение, которое не прошло проверку.

  • Тип: any
  • Назначение: диагностика причины ошибки

Примеры значений:

  • строка "abc" при проверке числа
  • undefined при обязательном поле
  • объект при ошибке вложенной структуры

constraints

Основной источник человекочитаемых сообщений об ошибках.

  • Тип: { [constraintName: string]: string }

Каждое свойство объекта constraints представляет:

  • ключ — имя валидатора (например, isEmail, minLength)
  • значение — сообщение об ошибке

Пример структуры:

{
  isEmail: "email must be an email",
  minLength: "email is too short"
}

Особенность: Один ValidationError может содержать несколько нарушенных правил одновременно.


children

Массив вложенных ValidationError, возникающий при валидации сложных объектов.

  • Тип: ValidationError[]
  • Назначение: описание ошибок во вложенных DTO или массивах объектов

Пример сценария

Если объект имеет структуру:

user: {
  profile: {
    age: "abc"
  }
}

ошибка по age будет находиться в:

children → children → ValidationError

Ключевая характеристика: ValidationError формирует дерево, а не плоский список.


contexts

Дополнительные контексты ошибок, добавляемые некоторыми валидаторами.

  • Тип: { [type: string]: ValidationErrorContext }
  • Используется для расширенной диагностики

Пример применения:

  • кастомные валидаторы
  • хранение метаданных о причине ошибки
  • передача дополнительных параметров проверки

Иерархическая модель ошибок

ValidationError формирует древовидную структуру, отражающую форму проверяемого объекта.

Принцип построения дерева

  • корневой ValidationError соответствует объекту верхнего уровня
  • свойства объекта представлены в children
  • вложенные объекты порождают новые уровни ValidationError

Пример структуры

User (root ValidationError)
 ├── email (constraints)
 ├── password (constraints)
 └── profile (children)
       └── age (constraints)

Поведение при различных типах данных

Простые объекты

При валидации плоской структуры children обычно пуст:

{
  property: "email",
  constraints: { isEmail: "invalid email" },
  children: []
}

Вложенные объекты

При использовании ValidateNested формируется дерево:

  • каждый уровень DTO становится узлом
  • ошибки пробрасываются вниз по структуре

Массивы

При валидации массивов каждый элемент рассматривается как отдельный узел:

users[0] → ValidationError
users[1] → ValidationError

В children могут находиться ошибки конкретных индексов.


Отличие constraints от children

constraints

  • описывают ошибки текущего свойства
  • содержат текстовые сообщения
  • являются конечным уровнем дерева

children

  • описывают структуру вложенных объектов
  • содержат другие ValidationError
  • формируют иерархию

Преобразование ValidationError в плоский формат

На практике ValidationError часто преобразуется в линейный список для API-ответов.

Рекурсивный обход

Алгоритм обработки обычно включает:

  • проверку constraints
  • сбор сообщений
  • рекурсивный обход children

Пример логики:

если constraints существует → добавить ошибки
если children существует → углубиться рекурсивно

Особенности работы с target

Поле target сохраняет ссылку на исходный объект без копирования.

Это приводит к нескольким важным последствиям:

  • возможна мутация исходных данных через ссылку
  • объект может быть большим по объёму памяти
  • одинаковый target встречается в нескольких ValidationError

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

Кастомные валидаторы могут формировать ValidationError с дополнительной информацией:

  • расширенные constraints
  • заполненные contexts
  • нестандартные вложенные структуры children

Это позволяет интегрировать сложные бизнес-правила в стандартную модель ошибок.


Типичные сценарии использования структуры

Формирование ответа API

ValidationError используется как промежуточный формат перед сериализацией:

  • извлечение constraints
  • преобразование дерева в список сообщений
  • группировка по полям

Логирование ошибок валидации

Часто сохраняется:

  • property
  • value
  • constraints

без полного target для уменьшения объёма логов.


Отладка DTO-структур

Дерево children позволяет определить:

  • на каком уровне вложенности произошла ошибка
  • какой именно DTO некорректен
  • какие данные передавались на каждом уровне

Особенности сериализации

ValidationError не является чистым JSON-объектом:

  • содержит циклические ссылки через target
  • включает вложенные объекты произвольной глубины
  • требует ручной обработки при JSON.stringify

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