Форматирование сообщений для пользователя

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

Типичная структура ошибки выглядит как:

  • message — человекочитаемый текст
  • type — тип нарушения правила (required, min, matches и т.д.)
  • path — путь к полю в объекте данных

При этом YupResolver преобразует внутренний формат Yup в формат, ожидаемый библиотекой управления формами, сохраняя при этом семантику вложенных полей.


Преобразование сообщений в YupResolver

YupResolver выступает промежуточным слоем между схемой валидации и UI-слоем. Его задача — не только передать ошибки, но и корректно привести их к структуре, удобной для отображения.

Основные этапы преобразования:

  1. Выполнение валидации схемы
  2. Сбор всех ошибок (или первой, в зависимости от режима abortEarly)
  3. Нормализация путей полей
  4. Формирование объекта ошибок формы

Ключевой момент — сохранение соответствия между вложенной структурой данных и плоским представлением ошибок.


Форматирование текстов сообщений

Сообщения могут задаваться непосредственно в схеме Yup. Именно этот уровень чаще всего определяет финальный текст, который увидит пользователь.

Пример:

import * as yup from "yup";

const schema = yup.object({
  email: yup
    .string()
    .required("Поле email обязательно для заполнения")
    .email("Некорректный формат email"),

  age: yup
    .number()
    .min(18, "Минимальный возраст — 18 лет")
});

YupResolver не изменяет текст сообщений, а лишь транспортирует их в форму. Это означает, что вся логика формулировки сообщений должна быть заложена в схеме.


Локализация сообщений

Форматирование сообщений часто связано с необходимостью поддержки нескольких языков. В этом случае Yup позволяет задавать сообщения через функции или внешние словари.

Распространённый подход — использование фабрики сообщений:

const messages = {
  required: "Обязательное поле",
  email: "Неверный email",
  min: (min) => `Минимальное значение: ${min}`
};

const schema = yup.object({
  username: yup.string().required(messages.required),
  email: yup.string().required(messages.required).email(messages.email),
  age: yup.number().min(18, messages.min(18))
});

YupResolver не занимается интернационализацией, но корректно сохраняет уже локализованные строки без дополнительной обработки.


Форматирование вложенных ошибок

При работе с вложенными объектами ключевым аспектом становится сохранение пути ошибки. Например:

const schema = yup.object({
  profile: yup.object({
    firstName: yup.string().required("Имя обязательно"),
    lastName: yup.string().required("Фамилия обязательна")
  })
});

После валидации YupResolver формирует структуру:

  • profile.firstName
  • profile.lastName

Такой формат позволяет UI-компонентам напрямую связывать сообщение с конкретным полем, не выполняя дополнительного парсинга.


Ошибки массивов и индексирование

Особое внимание требуется при работе с массивами. Yup возвращает ошибки с индексированными путями:

const schema = yup.object({
  users: yup.array().of(
    yup.object({
      name: yup.string().required("Имя обязательно")
    })
  )
});

Результат валидации:

  • users[0].name
  • users[1].name

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


Управление детализацией сообщений

Сообщения могут быть как общими, так и специфичными для конкретного правила. В Yup каждая проверка может иметь собственный текст, что позволяет формировать многоуровневую систему сообщений.

Пример различий:

  • "Обязательное поле" — базовое сообщение required
  • "Минимум 8 символов" — сообщение для min
  • "Пароль слишком простой" — кастомная логика matches

YupResolver не агрегирует сообщения, если включён режим детальной валидации. В результате каждое правило может возвращать отдельное сообщение для одного поля.


Режимы агрегации сообщений

Поведение формирования сообщений зависит от параметра abortEarly в Yup:

  • abortEarly: true — возвращается первая найденная ошибка
  • abortEarly: false — возвращаются все ошибки поля

YupResolver учитывает этот режим и формирует объект ошибок соответственно. При отключённом раннем завершении сообщения могут быть агрегированы в массив или объединены в зависимости от внутренней реализации формы.


Преобразование нестандартных сообщений

Иногда требуется преобразовать сообщение перед отображением. Это может быть полезно для:

  • добавления префиксов
  • унификации стиля текста
  • логирования

Типичный подход — постобработка на уровне формы:

const formatMessage = (message) => `[Ошибка] ${message}`;

Однако YupResolver не предоставляет встроенного механизма форматирования текста сообщений, оставляя этот слой внешней логике.


Согласование структуры ошибок с UI

Финальная цель форматирования — корректное отображение в интерфейсе. Обычно UI ожидает структуру:

  • ключ поля → строка сообщения

или

  • ключ поля → массив сообщений

YupResolver обеспечивает совместимость с этой моделью, преобразуя результат Yup в объект, где каждый путь соответствует конкретному элементу формы.


Поведение при отсутствии сообщений

Если сообщение не задано явно в схеме, Yup использует внутренние дефолтные строки. Эти строки зависят от типа ошибки и версии библиотеки.

YupResolver не заменяет и не локализует такие сообщения, поэтому их внешний вид может отличаться от кастомных строк, заданных разработчиком.


Консистентность формулировок

При проектировании сообщений важно соблюдать единый стиль формулировок:

  • либо императивный стиль: «Введите email»
  • либо описательный: «Email должен быть указан»
  • либо технический: «email is required»

YupResolver не вмешивается в стиль сообщений, но неконсистентность становится заметной на уровне UI, поскольку все сообщения отображаются в едином контексте формы без дополнительной обработки.


Интеграция с формами и отображением ошибок

В связке с системами управления формами сообщения используются напрямую из объекта ошибок. Типичный сценарий отображения:

  • доступ по имени поля
  • вывод текста рядом с input-компонентом
  • динамическое обновление при изменении значения

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