Как исправить ошибку «is not a function» в веб-клиенте 1С при записи документа?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет IT и автоматизация бизнеса
← На главную

При работе в веб-клиенте 1С:Предприятие разработчики и администраторы иногда сталкиваются с трудновоспроизводимыми ошибками JavaScript. Одной из наиболее коварных является ошибка «... is not a function» (или ее устаревший аналог «undefined is not a function»), возникающая в момент интерактивных действий пользователя — например, при нажатии кнопки «Записать и закрыть». Особенность этой проблемы в том, что она может проявляться бессистемно: лишь у некоторых пользователей и только для части документов.

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

Почему возникает ошибка «is not a function» в веб-клиенте?

Для того чтобы понять природу этой ошибки, необходимо заглянуть под капот веб-клиента 1С. Когда пользователь запускает систему через браузер (например, Google Chrome), платформа компилирует программный код управляемых форм и клиентских модулей (директива &НаКлиенте) в динамические файлы JavaScript. Эти скрипты передаются веб-серверу (IIS или Apache) и исполняются непосредственно в браузере.

Сбой «is not a function» означает, что интерпретатор JavaScript на стороне браузера пытается вызвать метод у объекта, который в данный момент равен undefined, null или имеет другой тип данных, не поддерживающий этот метод. Рассмотрим основные причины этого явления:

  1. Нестабильность конкретного релиза платформы 1С. В некоторых релизах платформы (в частности, в ветке 8.3.13, например 8.3.13.1513) присутствуют внутренние ошибки трансляции кода 1С в JavaScript. Платформа генерирует некорректный JS-код при обработке определенных событий формы или при передаче сложных типов данных между клиентом и сервером.
  2. Агрессивное кэширование на стороне веб-сервера IIS или браузера. После обновления конфигурации или платформы файлы скриптов (например, mod_main_...js) обновляются на сервере. Однако браузер пользователя или кэш IIS могут продолжать использовать старые версии скриптов. В результате код пытается вызвать функцию по обфусцированному (сокращенному) имени, которого в новой версии сборки уже не существует.
  3. Наличие скрытых модальных вызовов. Если конфигурация была перенесена или адаптирована из старых версий (например, глубоко доработанная «Управление торговлей 10.3»), в общих модулях при записи документа могут вызываться устаревшие синхронные методы вроде Предупреждение() или Вопрос(). Современные браузеры блокируют подобные вызовы, что приводит к критической ошибке JavaScript.
  4. Сбои при интеграции с внешними системами (HTTP-запросы). Если при записи документа происходит синхронное или асинхронное получение данных из внешних систем (например, JIRA), некорректный или пустой ответ сервера (ошибки 500, 403) может привести к тому, что переменная в 1С примет значение Неопределено. При попытке обработать этот результат на клиенте JavaScript выдаст ошибку отсутствия функции.

---

Шаг 1. Локализация ошибки через DevTools браузера

Поскольку ошибка возникает на клиенте, стандартный журнал регистрации 1С на сервере не зафиксирует подробности сбоя. Нам необходимо использовать встроенные инструменты разработчика в браузере Chrome.

Разберем алгоритм действий при возникновении ошибки:

  1. Когда на экране пользователя появляется окно с ошибкой, не закрывайте его и не перезагружайте страницу.
  2. Нажмите клавишу F12 (или комбинацию клавиш Ctrl + Shift + I) для открытия панели разработчика Chrome DevTools.
  3. Перейдите на вкладку Console (Консоль).
  4. Найдите строку ошибки, выделенную красным цветом (например, Uncaught TypeError: jfa.toUpperCase is not a function).
  5. Раскройте стек вызовов (Call Stack), нажав на стрелочку рядом с ошибкой. По именам функций и файлов JS (например, mod_main_mainform.js) мы сможем определить, какое событие формы (ПередЗаписью, ПриЗаписи) или какой обработчик ожидания вызвал сбой.

---

Шаг 2. Настройка сквозной отладки в режиме HTTP

Для детального анализа поведения системы мы можем подключить отладчик 1С непосредственно к сессии веб-клиента. Проанализируем, как настроить отладку по шагам:

  1. Убедимся, что на сервере 1С разрешена отладка по протоколу HTTP. В конфигурационном файле службы сервера или в параметрах запуска должен быть указан ключ -debug -http.
  2. В конфигураторе 1С перейдем в меню Сервис — Параметры — Запуск 1С:Предприятия — Дополнительные.
  3. Включим отладку при запуске и выберем тип отладки HTTP.
  4. В пользовательском режиме веб-клиента в меню «Параметры» проверим, что отладка активна.
  5. В конфигураторе откроем меню Отладка — Подключение, найдем в списке доступных предметов отладки сессию нашего веб-клиента и нажмем Подключить.
  6. В меню Отладка — Настройка отладки установим флажок Останавливаться по ошибке. Это позволит конфигуратору автоматически перехватить управление в момент возникновения исключения, и мы увидим точную строку кода 1С, которая привела к сбою JavaScript.

---

Шаг 3. Практические способы устранения проблемы

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

Способ 1. Обновление платформы 1С:Предприятие

Как показывает практика, в подавляющем большинстве случаев возникновение несистемных ошибок JavaScript в веб-клиенте на платформе версий 8.3.13.х связано с внутренними багами самого движка платформы. Обновление платформы на актуальный стабильный релиз (например, из веток 8.3.18, 8.3.20 или выше) полностью устраняет проблему некорректной генерации JS-кода.

Способ 2. Очистка кэша на стороне сервера и клиента

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

Способ 3. Перевод модальных окон на асинхронные вызовы

Если ваша конфигурация содержит элементы старых систем (например, блоки из УТ 10.3), критически важно избавиться от синхронных модальных окон. Браузеры блокируют их, что мгновенно вызывает ошибку is not a function на клиенте.

Рассмотрим пример рефакторинга кода. Предположим, у нас использовался старый синхронный вызов вопроса перед записью:


// Устаревший синхронный код, вызывающий ошибку в веб-клиенте
Режим = РежимДиалогаВопрос.ДаНет;
Ответ = Вопрос("Вы действительно хотите записать документ?", Режим);
Если Ответ = КодВозвратаДиалога.Да Тогда
    Записать();
КонецЕсли;

Мы должны переписать этот код с использованием асинхронного метода ПоказатьВопрос и описания оповещения:


// Современный асинхронный код, корректно работающий в браузере
&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
    
    // Если проверка уже пройдена, не задаем вопрос повторно
    Если Не ДополнительныеСвойства.Свойство("ПроверкаПройдена") Тогда
        Отказ = Истина; // Блокируем стандартную запись
        
        Режим = РежимДиалогаВопрос.ДаНет;
        Оповещение = Новый ОписаниеОповещения("ПослеВопросаОЗаписи", ЭтотОбъект, ПараметрыЗаписи);
        ПоказатьВопрос(Оповещение, "Вы действительно хотите записать документ?", Режим);
    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура ПослеВопросаОЗаписи(Результат, ДополнительныеПараметры) Экспорт
    Если Результат = КодВозвратаДиалога.Да Тогда
        ДополнительныеСвойства.Вставить("ПроверкаПройдена", Истина);
        // Повторно вызываем запись, которая теперь пройдет без вопросов
        Записать(ДополнительныеПараметры);
    КонецЕсли;
КонецПроцедуры

Способ 4. Безопасная обработка HTTP-ответов от внешних систем

При интеграции с JIRA или другими системами по HTTP-протоколу сбой сети может вернуть пустой или некорректный ответ. Если этот ответ сразу передается на клиент без валидации, обращение к его свойствам на клиенте рухнет с ошибкой JavaScript.

Разберем пример безопасной обработки данных:


// НЕБЕЗОПАСНЫЙ ВАРЯНТ (может вызвать ошибку JavaScript на клиенте)
&НаКлиенте
Процедура ОбработатьОтветJira(ДанныеОтвета)
    // Если ДанныеОтвета пришли как Неопределено, этот вызов вызовет "is not a function"
    СтатусЗадачи = ДанныеОтвета.Получить("status"); 
КонецПроцедуры

// БЕЗОПАСНЫЙ ВАРИАНТ
&НаКлиенте
Процедура ОбработатьОтветJiraБезопасно(ДанныеОтвета)
    
    // Проверяем тип пришедших данных перед обращением к методам
    Если ДанныеОтвета = Неопределено Тогда
        ПоказатьПредупреждение(, "Не удалось получить данные из JIRA. Проверьте подключение.");
        Возврат;
    КонецЕсли;
    
    Если ТипЗнч(ДанныеОтвета) = Тип("Соответствие") Тогда
        СтатусЗадачи = ДанныеОтвета.Получить("status");
        Если СтатусЗадачи <> Неопределено Тогда
            // Продолжаем логику обработки
        КонецЕсли;
    Иначе
        ПоказатьПредупреждение(, "Получены данные неверного формата.");
    КонецЕсли;
    
КонецПроцедуры

Применяя данные защитные механизмы в кодовой базе и своевременно обновляя платформу 1С:Предприятие, мы обеспечим стабильную и бесперебойную работу пользователей в режиме веб-клиента без раздражающих ошибок интерфейса.

← На главную