В экосистеме Intl ошибка RangeError
является одной из наиболее характерных, поскольку большинство функций
интернационализации опираются на строго ограниченные наборы допустимых
значений. Любое отклонение от стандартизированных параметров приводит к
немедленному выбросу исключения.
Наиболее частый источник RangeError — передача
недопустимой строки локали. Все конструкторы Intl
используют механизм locale resolution, основанный на BCP
47.
new Intl.DateTimeFormat("xx-INVALID");
Подобная строка не соответствует спецификации языковых тегов, что приводит к:
RangeError: Invalid language tag: xx-INVALIDАналогично ошибка возникает при некорректных расширениях:
new Intl.NumberFormat("en-US-u-invalid-extension");
Хотя механизм расширений допускает гибкость, неизвестные ключи или значения могут нарушать парсинг.
Intl.DateTimeFormat строго проверяет IANA time zone
database. Любое отклонение от списка допустимых зон приводит к
RangeError.
new Intl.DateTimeFormat("en-US", {
timeZone: "Moon/Crater"
});
Причина ошибки:
Area/LocationМножество опций Intl ограничены фиксированными наборами
значений:
numberingSystemcalendarcollationcaseFirsthourCycleПример:
new Intl.DateTimeFormat("en", {
calendar: "unknown-calendar"
});
Результат:
RangeError: invalid calendarАналогично:
new Intl.NumberFormat("en", {
numberingSystem: "latin-extreme"
});
Некоторые комбинации параметров также могут приводить к
RangeError, когда спецификация исключает одновременное
использование опций.
new Intl.DateTimeFormat("en", {
dateStyle: "full",
year: "numeric"
});
Если комбинация не допускается реализацией движка, возникает ошибка диапазона допустимых конфигураций.
TypeError в Intl возникает не из-за
диапазона значений, а из-за нарушения типов данных, контекста вызова или
структуры аргументов.
Методы прототипов Intl зависят от внутреннего состояния
объекта. При отрыве метода от экземпляра нарушается связь с внутренними
слотами.
const format = new Intl.NumberFormat("en").format;
format(1000);
Типичная ошибка:
TypeError: Illegal invocationПричина:
[[NumberFormat]] контекстаКонструкторы Intl ожидают объект опций или
undefined. Передача примитивов вызывает
TypeError.
new Intl.DateTimeFormat("en", "invalid-options");
Результат:
TypeError: options must be an objectДопустимые формы:
undefined{}Методы вроде formatToParts, format,
resolvedOptions требуют корректного экземпляра.
Intl.NumberFormat.prototype.format(100);
Здесь отсутствует привязка к экземпляру форматтера, поэтому внутренние данные отсутствуют, что приводит к:
TypeError: Intl.NumberFormat.prototype.format called on incompatible receiverИзвлечение методов без привязки контекста приводит к аналогичным проблемам:
const { format } = new Intl.DateTimeFormat("en");
format(new Date());
Функция теряет ссылку на внутренние настройки локали и параметров форматирования.
Поведение ошибок в Intl подчиняется строгой логике:
RangeError возникает при:
TypeError возникает при:
thisIntlНесмотря на стандартизацию ECMA-402, отдельные JavaScript-движки демонстрируют различия в деталях сообщений об ошибках:
Illegal invocationRangeErrorОбщим остаётся принцип: любая ошибка интернационализации классифицируется либо как нарушение диапазона допустимых значений, либо как нарушение типов и контекста выполнения.
При создании экземпляра Intl выполняется несколько
этапов:
На каждом этапе возможны различные категории отказов:
RangeErrorTypeErrorfunction formatPrice(value, locale) {
return new Intl.NumberFormat(locale, {
style: "currency",
currency: "US Dollar"
}).format(value);
}
Ошибка возникает на этапе создания форматтера:
RangeError: invalid currency codeКорректный формат требует ISO 4217:
currency: "USD"
Другой пример:
const dtf = Intl.DateTimeFormat("en-US");
dtf.format.call({}, new Date());
Ошибка:
TypeError: format called on incompatible receiverПричина — подмена контекста объекта.
Система Intl проектировалась как строго
детерминированная. Это означает:
Такой подход обеспечивает одинаковое поведение форматирования во всех окружениях, но увеличивает строгость проверки входных данных.
При вложенном использовании Intl ошибки не
маскируются:
new Intl.DateTimeFormat(
new Intl.NumberFormat("en").format(1000)
);
Если внутренний вызов возвращает некорректную строку локали, ошибка
RangeError возникает на внешнем уровне, без попыток
восстановления.
Объект options проходит глубокую нормализацию:
Любое нарушение приводит либо к:
RangeError (если значение вне множества)TypeError (если структура объекта нарушена)Поведение ошибок можно формализовать следующим образом:
TypeErrorRangeErrorЭта модель делает Intl одной из наиболее строго
типизированных подсистем JavaScript, несмотря на отсутствие статической
типизации в языке.