При разработке интеграционных механизмов на базе веб-сервисов (WS) или HTTP-сервисов в 1С разработчики нередко сталкиваются с ситуацией, когда выполнение алгоритма внезапно прерывается на простых операциях. Типичный сценарий: клиент отправляет данные, сервер начинает обработку, но на строке Справочники.Материалы.СоздатьЭлемент() происходит мгновенный разрыв WS-соединения. При этом блок Попытка ... Исключение не срабатывает, в журнал регистрации не записывается ошибка выполнения, а попытка вычислить выражение в отладчике приводит к зависанию конфигуратора. Разберем подробно, почему возникает такое поведение платформы и как правильно локализовать и устранить неисправность.
Для понимания природы проблемы проанализируем, как платформа 1С:Предприятие исполняет программный код в неинтерактивных сеансах (веб-сервисы, HTTP-сервисы, COM-соединения, фоновые задания):
Попытка ... Исключение перехватывает исключительно исключения времени выполнения (runtime exceptions). Если же в модуле присутствует синтаксическая ошибка или вызов метода, недоступного в текущем контексте (например, клиентской функции), ошибка происходит на этапе предварительной компиляции модуля платформой. В неинтерактивном сеансе ошибка сборки модуля приводит к аварийному завершению потока и закрытию сессии.СоздатьЭлемент() или СоздатьГруппу() платформа выполняет инициализацию объекта в памяти. В этот момент происходит обязательная компиляция модуля объекта, модуля менеджера справочника, а также модулей обработчиков подписок на события. Если хотя бы в одной процедуре модуля объекта содержится синтаксическая некорректность для сервера/внешнего соединения, модуль не может быть скомпилирован, даже если сам исполняемый алгоритм в эту процедуру не заходит.Состояние(), Предупреждение(), Вопрос() или обращение к глобальным переменным интерактивного контекста, корректно работает в режиме толстого или тонкого клиента, но делает модуль невалидным при вызове из веб-сервиса.Разберем по шагам, как выявить модуль, вызывающий падение соединения веб-сервиса:
СправочникОбъект. Модули обработчиков подписок должны иметь установленный флаг «Сервер» или «Вызов сервера», а также не содержать прямого обращения к элементам пользовательского интерфейса.EXCP, EXCPCNTX и CALL в файле logcfg.xml. Это позволит увидеть точный стек вызовов и причину завершения рабочего процесса сеанса.Рассмотрим варианты исправления ситуации в зависимости от архитектуры конфигурации.
Если в модуле объекта справочника необходим вывод сообщений для пользователя при интерактивной работе, обернем такой код в инструкции препроцессора, исключающие его исполнение на стороне сервера или во внешних вызовах:
Процедура ПриУстановкеНовогоКода(СтандартнаяОбработка, Префикс)
#Если Клиент Тогда
Состояние("Выполняется установка нового кода элемента...");
#КонецЕсли
// Основная логика формирования кода
Префикс = "МАТ-";
КонецПроцедуры
В неинтерактивном сеансе веб-сервиса код внутри блока #Если Клиент будет полностью проигнорирован препроцессором, и модуль успешно скомпилируется сервером 1С.
При проектировании сервисов интеграции рекомендуется разделять интерактивный интерфейсный код и серверную бизнес-логику. Посмотрим на пример корректной реализации создания элемента внутри веб-сервиса:
Функция СоздатьНовыйМатериал(НаименованиеМатериала, Артикул) Экспорт
УстановитьПривилегированныйРежим(Истина);
Попытка
НовыйОбъект = Справочники.Материалы.СоздатьЭлемент();
НовыйОбъект.Наименование = НаименованиеМатериала;
НовыйОбъект.Артикул = Артикул;
// Запись объекта с отключением стандартных интерактивных проверок при необходимости
НовыйОбъект.Записать();
Возврат НовыйОбъект.Ссылка;
Исключение
ИнформацияОбОшибке = ОписаниеОшибки();
ЗаписьЖурналаРегистрации("Интеграция.WS", УровеньЖурналаРегистрации.Ошибка,,, ИнформацияОбОшибке);
ВызватьИсключение "Ошибка при создании элемента: " + ИнформацияОбОшибке;
КонецПопытки;
КонецФункции
Таким образом, главная причина внезапного закрытия веб-сервисного соединения без генерации стандартного исключения кроется в ошибках компиляции контекста модулей. Регулярная проверка конфигурации в режимах «Сервер» и «Внешнее соединение» позволяет предотвратить подобные сбои на этапе разработки.