Валидация данных в Ajv сопровождается формированием структурированного массива ошибок, каждая из которых содержит техническую информацию о несоответствии JSON-схеме. По умолчанию сообщения об ошибках представлены на английском языке и ориентированы на разработчика, а не на конечного пользователя. Локализация в этом контексте означает преобразование этих технических сообщений в человеко-читаемый формат на нужном языке с учётом контекста приложения.
В основе системы ошибок Ajv лежит массив errors,
формируемый после вызова validate(). Каждый элемент массива
содержит поля:
keyword — имя нарушенного ключевого правила (например,
type, required, minLength)instancePath — путь к данным, где обнаружена
ошибкаschemaPath — путь к правилу схемыparams — параметры ошибкиmessage — стандартное текстовое сообщениеИменно поле message чаще всего подвергается локализации,
однако для полноценного перевода требуется учитывать и остальные
поля.
Типичная ошибка Ajv выглядит следующим образом:
{
"instancePath": "/user/age",
"schemaPath": "#/properties/user/properties/age/minimum",
"keyword": "minimum",
"params": {
"comparison": ">=",
"limit": 18
},
"message": "must be >= 18"
}
Проблема локализации заключается в том, что поле message
не является самостоятельным источником истины — оно генерируется на
основе keyword и params. Поэтому простая
замена строки недостаточна, требуется переопределение генерации
сообщений.
В Ajv можно управлять генерацией текстов ошибок через опцию:
const ajv = new Ajv({
messages: false
});
При отключении стандартных сообщений поле message может
отсутствовать или быть минимальным, что позволяет полностью взять
контроль над локализацией.
Одним из основных механизмов локализации является ключ схемы
errorMessage.
const schema = {
type: "object",
properties: {
age: {
type: "number",
minimum: 18,
errorMessage: {
minimum: "Возраст должен быть не меньше 18 лет",
type: "Возраст должен быть числом"
}
}
}
};
При использовании этого подхода Ajv заменяет стандартные сообщения на пользовательские, привязанные к конкретным keywords.
Особенность заключается в том, что errorMessage работает
на уровне схемы и позволяет локализовать ошибки без постобработки.
При необходимости централизованной обработки используется
преобразование массива errors после валидации:
const translateError = (error) => {
switch (error.keyword) {
case "type":
return `Неверный тип данных в ${error.instancePath}`;
case "minimum":
return `Значение меньше допустимого минимума`;
default:
return `Ошибка валидации`;
}
};
const localizedErrors = validate.errors.map(translateError);
Этот подход позволяет отделить логику схемы от языковой логики приложения.
Существует специализированный пакет для локализации —
ajv-i18n. Он предоставляет готовые функции перевода массива
ошибок.
Пример использования:
import localize fr om "ajv-i18n";
validate(data);
if (validate.errors) {
localize.ru(validate.errors);
}
После вызова функции ошибки модифицируются прямо в массиве
errors, а поле message заменяется на
локализованное значение.
Поддерживаются различные языки:
enruesdefrМеханизм работает через сопоставление keyword и
params с заранее подготовленными шаблонами.
Ajv позволяет создавать собственные keywords через
addKeyword, что открывает возможность полной кастомизации
сообщений.
ajv.addKeyword({
keyword: "positiveNumber",
validate: (schema, data) => typeof data === "number" && data > 0,
errors: true,
metaSchema: {
type: "boolean"
}
});
Для локализации ошибок в таком случае необходимо вручную задавать сообщение:
validate.errors.push({
keyword: "positiveNumber",
message: "Число должно быть положительным",
instancePath: "/amount"
});
Этот подход используется при сложной бизнес-логике, где стандартные keywords недостаточны.
Ajv различает несколько типов ошибок:
type)required,
additionalProperties)minimum, maximum)minLength, pattern)format)Каждый тип требует собственного шаблона перевода. Например:
type
Ожидался тип number
required
Отсутствует обязательное поле: user.name
pattern
Строка не соответствует требуемому формату
Унификация перевода без учёта keyword приводит к потере точности сообщений.
Поле instancePath критично для формирования понятного
сообщения. Оно указывает, где именно возникла ошибка в объекте
данных.
Пример:
"/user/profile/email"
При локализации часто требуется преобразование пути в читаемый формат:
const formatPath = (path) =>
path.replace("/", "").replace(/\//g, ".");
Результат:
user.profile.email
Это позволяет интегрировать путь в локализованные сообщения:
Поле user.profile.email содержит ошибку формата
Ajv по умолчанию может возвращать несколько ошибок для одного объекта. Это влияет на локализацию, так как требуется объединение сообщений.
const messages = validate.errors.map(e => translateError(e)).join("\n");
При сложных схемах важно группировать ошибки по
instancePath:
const grouped = validate.errors.reduce((acc, err) => {
acc[err.instancePath] = acc[err.instancePath] || [];
acc[err.instancePath].push(err);
return acc;
}, {});
Это позволяет формировать структурированные локализованные отчёты.
Распространённый подход — использование внешних словарей:
const dictionary = {
required: "Поле обязательно для заполнения",
type: "Неверный тип данных",
minimum: "Значение слишком маленькое"
};
И последующее сопоставление:
const message = dictionary[error.keyword] || "Ошибка валидации";
Такой подход упрощает поддержку мультиязычности, так как перевод отделяется от логики схем.
В Ajv v8 изменилась структура некоторых ошибок и поведение сообщений:
errorMessageallErrorsparamsЭто влияет на стабильность локализаторов, которые зависят от
структуры errors. При обновлении версии требуется проверка
совместимости переводов.
Типичный pipeline с локализацией ошибок:
validate(data)validate.errorsПример:
if (!validate(data)) {
const localized = validate.errors.map(localizeError);
return {
success: false,
errors: localized
};
}
Базовая модель локализации строится вокруг ключа
keyword:
| keyword | шаблон |
|---|---|
| type | Неверный тип |
| required | Отсутствует поле |
| minimum | Значение меньше допустимого |
| pattern | Неверный формат строки |
Расширение этой таблицы позволяет поддерживать сложные схемы без изменения логики валидации.
Некоторые ошибки требуют учёта контекста схемы:
message: ({ instancePath, params }) =>
`Ошибка в ${instancePath}: значение должно быть >= ${params.lim it}`
Это позволяет генерировать динамические локализованные сообщения, зависящие от входных данных схемы.
При работе с локализацией в Ajv важно учитывать:
errors не предназначена для UI напрямуюparamsinstancePathЭти особенности делают локализацию не побочным эффектом, а отдельным слоем архитектуры валидации данных.