Валидационные ошибки в Vest представляют собой структурированное дерево, в котором каждая ошибка привязана к конкретному тесту и полю. Архитектура библиотеки предполагает, что ошибки не существуют в виде плоского списка: они группируются по полям, группам и условиям выполнения тестов, что позволяет точно адресовать каждое нарушение.
Каждый тест в Vest ассоциируется с конкретным полем (field). При провале проверки библиотека фиксирует сообщение ошибки внутри внутреннего состояния результата валидации.
Типичная структура ошибок выглядит как объект:
{
username: ["Имя пользователя слишком короткое"],
password: ["Пароль должен содержать минимум 8 символов"]
}
Ключи объекта соответствуют именам полей, а значения представляют массивы сообщений. Даже если ошибка одна, она хранится в массиве, что упрощает расширение логики (например, добавление нескольких правил на одно поле).
Основной механизм доступа к ошибкам в Vest основан на выборочном чтении данных из результата выполнения схемы валидации.
import { create, test } from "vest";
const validate = create((data = {}) => {
test("username", "USERNAME_REQUIRED", () => {
if (!data.username) {
return "Имя пользователя обязательно";
}
});
test("username", "USERNAME_MIN_LENGTH", () => {
if (data.username && data.username.length < 3) {
return "Минимальная длина — 3 символа";
}
});
});
После выполнения:
const result = validate({ username: "ab" });
Доступ к ошибкам конкретного поля осуществляется через объект результата:
result.getErrors("username");
Возвращаемое значение:
["Минимальная длина — 3 символа"]
Такой способ позволяет изолировать ошибки конкретного поля без необходимости обхода всей структуры результата.
getErrors для изолированного доступаМетод getErrors(fieldName) является ключевым
инструментом работы с частичными ошибками. Он возвращает только те
сообщения, которые относятся к указанному полю.
Особенности поведения:
const errors = result.getErrors("password");
При отсутствии ошибок:
[]
Это позволяет безопасно использовать результат без дополнительных
проверок на undefined.
Полный объект ошибок доступен через:
result.errors
Пример структуры:
{
username: ["Имя пользователя обязательно"],
password: ["Пароль слишком короткий", "Пароль должен содержать цифру"]
}
Для извлечения конкретной ошибки вручную можно использовать стандартные операции:
const firstPasswordError = result.errors.password?.[0];
или безопасную деструктуризацию:
const { password = [] } = result.errors;
Vest поддерживает группировку тестов, что влияет на структуру ошибок. В этом случае доступ к конкретным ошибкам становится более контекстным.
import { group, test, create } from "vest";
const validate = create(() => {
group("auth", () => {
test("email", "INVALID_EMAIL", () => {
return "Некорректный email";
});
test("password", "WEAK_PASSWORD", () => {
return "Слишком слабый пароль";
});
});
});
Результирующий доступ:
result.getErrors("email");
Несмотря на группировку, интерфейс доступа остаётся плоским, что позволяет не учитывать структуру групп при чтении ошибок.
В реальных интерфейсах часто требуется не массив, а только первое сообщение. Vest не навязывает отдельный метод для этого, но предоставляет удобный способ извлечения:
const firstError = result.getErrors("username")[0];
или через результат:
const firstError = result.errors.username?.[0];
Такой подход применяется при отображении ошибок в UI под полем ввода.
Для определения состояния поля используется проверка длины массива ошибок:
const hasUsernameError = result.getErrors("username").length > 0;
или:
const hasError = !!result.errors.username?.length;
Это важный механизм для динамического управления состоянием интерфейса.
В случаях, когда несколько тестов возвращают ошибки для одного поля, они накапливаются в массиве:
test("password", "TOO_SHORT", () => "Слишком короткий");
test("password", "NO_NUMBER", () => "Нет цифры");
Результат:
["Слишком короткий", "Нет цифры"]
Порядок соответствует последовательности выполнения тестов, что позволяет управлять приоритетом отображения.
Vest поддерживает условные проверки, что влияет на наличие ошибок в результате. При пропуске теста ошибка в структуре отсутствует, что делает доступ к ошибкам предсказуемым:
test("age", "AGE_REQUIRED", () => {
if (!data.age) return "Возраст обязателен";
});
Если тест не выполняется, getErrors("age") возвращает
пустой массив, а не null или undefined.
Доступ к конкретным ошибкам часто используется для:
Пример блокировки отправки:
const result = validate(data);
if (result.hasErrors()) {
if (result.getErrors("email").length) {
// обработка ошибки email
}
}
При работе с результатами валидации важно учитывать отсутствие поля в объекте ошибок:
const message = result.errors?.username?.[0] || "";
Это предотвращает ошибки обращения к undefined и упрощает интеграцию в шаблонизаторы и UI-фреймворки.
errors и getErrorsИспользование errors:
result.errors.username
Использование getErrors:
result.getErrors("username")
Оба способа опираются на одну и ту же структуру данных, но отличаются уровнем безопасности и удобства.