В библиотеке Yup процесс валидации построен как последовательное
применение цепочки правил к значению схемы. Несмотря на декларативный
стиль описания схем, внутри движка существует несколько механизмов,
влияющих на то, как и когда прекращается проверка данных. Одним из
ключевых аспектов является управление прерыванием валидации, которое
напрямую связано с поведением флага abortEarly.
В Yup стандартная функция проверки validate принимает
опции, среди которых особое значение имеет параметр
abortEarly. Он определяет стратегию обработки ошибок при
валидации:
abortEarly: true — валидация прекращается при первой
найденной ошибкеabortEarly: false — выполняется полная проверка всех
правил и собираются все ошибкиПри включённом режиме раннего прерывания Yup ведёт себя как
последовательный фильтр: каждое правило проверяется по очереди, и при
обнаружении первого несоответствия дальнейшая проверка прекращается. Это
касается как встроенных валидаторов (required,
min, max, matches), так и
пользовательских тестов, определённых через test.
Пример поведения:
ValidationErrorТакой режим полезен в сценариях, где требуется минимальная нагрузка на проверку или быстрый фидбек о первом нарушении.
Когда abortEarly отключён, Yup переходит к агрегационной
модели. Все правила для каждого поля выполняются независимо от уже
найденных ошибок.
Результатом становится объект ValidationError,
содержащий массив inner, в котором перечислены все
найденные нарушения. Каждый элемент массива описывает отдельную ошибку с
указанием:
path) к полюtype)message)value)Такая модель используется в формах и системах, где важно предоставить пользователю полный список проблем за одну итерацию проверки.
Механизм прерывания тесно связан с тем, как Yup формирует структуру
ошибок. При отключённом abortEarly ошибки не выбрасываются
немедленно, а накапливаются внутри объекта
ValidationError.
Ключевые элементы:
message — агрегированное сообщение (часто первое по
порядку)errors — массив текстовых сообщенийinner — массив детализированных ошибокpath — путь до поля в объектеvalue — значение, вызвавшее ошибкуПри этом даже если одно поле содержит несколько нарушений, они
фиксируются отдельно, если это допускается структурой схемы (например,
вложенные test или массивы условий).
Функция test в Yup позволяет добавлять кастомные
проверки. Внутри неё также возможно управление логикой прерывания, хотя
оно реализуется неявно.
Yup.string().test('custom-check', function (value) {
if (!value) return true;
if (value.length < 5) {
return this.createError({ message: 'Слишком короткое значение' });
}
return true;
});
Когда используется createError, текущий тест считается
проваленным, и дальнейшие тесты для этого уровня схемы могут быть
остановлены в зависимости от abortEarly.
Важно, что внутри одного test нет встроенного механизма
“abort chain” — прерывание контролируется на уровне всей схемы, а не
отдельной функции.
Yup поддерживает сложные вложенные структуры: объекты, массивы,
комбинации схем. Поведение abortEarly распространяется
рекурсивно.
При проверке объекта:
abortEarly: true ошибка в первом невалидном поле
может остановить проверку остальных полей объектаДля массивов применяется дополнительный уровень итерации:
abortEarlyПри abortEarly: false возможна ситуация, когда один
элемент массива содержит несколько ошибок, и все они фиксируются
отдельно.
В реальных сценариях используются различные стратегии управления остановкой проверки.
Используется при:
Преимущество — минимальное время выполнения. Недостаток — отсутствие полной картины ошибок.
Используется при:
Позволяет собрать полный список ошибок и отобразить их одновременно.
Yup поддерживает асинхронные проверки, включая запросы к серверу
через test с async функцией.
Yup.string().test('check-remote', async function (value) {
const exists = await apiCheck(value);
if (!exists) {
return this.createError({ message: 'Значение не существует' });
}
return true;
});
В асинхронных схемах прерывание работает аналогично синхронным:
abortEarly: true промис отклоняется сразу после
первой ошибкиabortEarly: false все проверки дожидаются
завершенияОднако важно учитывать, что асинхронные тесты выполняются последовательно внутри одной ветки схемы, и их отмена не поддерживает нативного механизма остановки выполнения промисов.
Несмотря на терминологическое сходство с концепцией “abort”, Yup не
использует AbortController или сигналы отмены. Прерывание
реализовано исключительно на уровне логики выполнения цепочки
валидаторов.
Это означает:
testabortEarlyМеханизм прерывания часто используется как способ оптимизации сложных схем.
Примеры оптимизационных подходов:
required) перед
дорогими (test, async вызовы)when для условного включения
валидаторовПример условного прерывания:
Yup.string().when('type', {
is: 'email',
then: schema => schema.email().required(),
otherwise: schema => schema.required()
});
Хотя when не является механизмом abort, он позволяет
уменьшить количество выполняемых проверок, тем самым косвенно влияя на
точки остановки.
При больших схемах различие между режимами становится заметным:
abortEarly: true снижает количество выполняемых
тестовabortEarly: false увеличивает нагрузку за счёт полного
обхода дерева схемОсобенно это критично для:
При использовании concat, shape и
комбинированных схем порядок выполнения влияет на момент прерывания.
Yup выполняет проверку в порядке объявления схемы, поэтому:
abortEarly порядок влияет только на
порядок ошибок в innerМеханизм прерывания является частью более широкой модели исполнения Yup, где каждая схема представляет собой дерево проверок. AbortEarly фактически управляет глубиной обхода этого дерева в момент обнаружения несоответствия.
Внутренне это выражается через:
ValidationError или его
накоплениеТаким образом, abortEarly не является отдельной функцией, а встроен в алгоритм обхода схемы как управляющее условие продолжения выполнения.