В библиотеке Superstruct все ошибки валидации данных представлены единым специализированным типом — StructError. Это не просто сообщение о сбое проверки, а структурированный объект, содержащий полную информацию о том, где, почему и каким образом входные данные не соответствуют ожидаемой структуре.
Такой подход позволяет не только фиксировать факт ошибки, но и точно локализовать её внутри вложенных структур, массивов и сложных объектов.
Экземпляр ошибки содержит несколько ключевых полей:
Каждое из этих полей играет роль в построении диагностической информации, необходимой для обработки ошибок валидации.
value содержит исходные данные, которые были переданы в валидатор. Это может быть как простое значение, так и сложный объект или массив.
Особенность заключается в том, что value всегда отражает реальное состояние данных на момент ошибки, без преобразований и маскировки.
Поле path представляет собой массив, описывающий путь до элемента, вызвавшего ошибку.
Пример структуры:
['user', 'address', 'street']
Такой путь позволяет однозначно определить, где именно произошёл сбой:
Путь формируется динамически во время рекурсивной проверки структуры.
Поле key содержит имя текущего проверяемого свойства.
Если ошибка произошла внутри объекта, key указывает на конкретное поле. Если структура представляет собой массив, key может быть числовым индексом.
Поле type описывает правило, которое нарушено.
Это может быть:
Type не содержит фактического значения — только описание ожидаемого формата.
В Superstruct можно задавать дополнительные проверки через refinement-функции. Если ошибка возникает именно на этом уровне, поле refinement содержит имя соответствующего правила.
Пример использования:
Если refinement отсутствует, значит нарушение произошло на базовом уровне структуры.
Поле branch представляет собой массив значений, проходящих от корня структуры до точки ошибки.
Пример:
[
{ user: {...} },
{ address: {...} },
'Main Street'
]
Каждый элемент branch отражает промежуточное состояние данных на пути к ошибке. Это позволяет анализировать контекст, а не только финальный узел.
Метод failures() возвращает итератор всех обнаруженных ошибок валидации.
Каждый элемент содержит:
В отличие от самого StructError, который может агрегировать ошибки, failures() раскрывает их по отдельности, позволяя выполнять постобработку.
Каждое нарушение внутри failures() имеет следующую форму:
Эта структура используется при построении пользовательских сообщений и систем логирования.
Поле message формируется автоматически на основе остальных данных.
Оно объединяет:
Однако message не является единственным источником истины — он предназначен для быстрого восприятия, тогда как path и failures() используются для точного анализа.
При работе с глубоко вложенными объектами Superstruct постепенно накапливает информацию о пути ошибки.
Пример логики формирования:
Таким образом обеспечивается точная трассировка даже в сложных иерархиях данных.
Если структура содержит несколько нарушений, Superstruct:
Это позволяет избегать остановки проверки на первой ошибке и получать полную картину состояния данных.
StructError можно преобразовывать в JSON-подобные структуры, однако:
Поэтому для передачи между слоями системы чаще используют результат failures(), а не сам объект ошибки.
При обработке StructError обычно выделяются три уровня анализа:
Такое разделение позволяет строить как пользовательские сообщения, так и внутренние механизмы диагностики данных без потери информации о контексте выполнения проверки.