При разработке и отладке HTTP-сервисов в расширениях 1С:Предприятие программисты часто сталкиваются с ситуацией, когда код, успешно работающий в основной конфигурации, внезапно «падает» с ошибкой «ошибка инициализации общего модуля». Эта проблема может сбивать с толку, так как модуль физически существует, виден в дереве конфигурации и доступен в других сеансах. В рамках данной статьи мы подробно разберем, почему возникает эта ошибка и как обеспечить корректную работу общего модуля в контексте веб-вызовов.
Первым делом проанализируем саму формулировку ошибки. Если бы платформа действительно «не видела» модуль, мы бы получили сообщение вида Переменная не определена (ОбщегоНазначения). Ошибка «инициализации» означает, что платформа успешно нашла модуль, начала его компиляцию и выполнение раздела описания переменных или программного кода в основной части модуля (вне процедур и функций), но в этот момент произошло исключение.
Рассмотрим основные причины, по которым это происходит при вызове из HTTP-сервиса.
Это самая частая причина проблем с расширениями. По умолчанию любое новое расширение подключается в безопасном режиме. В этом режиме накладываются существенные ограничения на исполняемый код:
Если ваш HTTP-сервис вызывает метод модуля ОбщегоНазначения, а само расширение находится в безопасном режиме, инициализация модуля может завершиться ошибкой, особенно если модуль помечен как Привилегированный.
Как исправить:
УстановитьБезопасныйРежим() передается значение Ложь.HTTP-сервисы всегда выполняются на стороне сервера, причем в неинтерактивном режиме. Выясним причину возможного конфликта флагов. Для того чтобы модуль был доступен внутри HTTP-запроса, у него должны быть установлены соответствующие признаки в свойствах:
Если в коде инициализации модуля (в самом низу, после всех процедур) есть обращение к клиенту, например:
// В теле общего модуля
Если ИмяКомпьютера() = "Workstation01" Тогда
// Какая-то логика
КонецЕсли;
Такой код может отработать в обычном сеансе, но упасть в HTTP-сервисе, если платформа не сможет инициализировать среду окружения.
Проанализируем ситуацию, упомянутую автором: вызов ОбщегоНазначения.ПолучитьДанныеПользователя. Подобные методы почти всегда обращаются к ПараметрыСеанса.ТекущийПользователь или аналогичным.
При вызове HTTP-сервиса создается так называемый «ленивый сеанс». Если в модуле сеанса (в основной конфигурации или в расширении) не прописана логика инициализации параметров сеанса для данного вида соединения, то при первом же обращении к ним внутри общего модуля возникнет ошибка. Платформа попытается инициализировать модуль, дойдет до обращения к параметру сеанса, не найдет его и выдаст «ошибку инициализации».
Пример правильной инициализации в модуле сеанса:
Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
Если ТребуемыеПараметры = Неопределено Тогда
// Инициализация всех параметров при запуске
ПараметрыСеанса.ТекущийПользователь = Справочники.Пользователи.НайтиПоНаименованию(ИмяПользователя());
Иначе
// Инициализация по требованию
Для Каждого ИмяПараметра Из ТребуемыеПараметры Цикл
Если ИмяПараметра = "ТекущийПользователь" Тогда
ПараметрыСеанса.ТекущийПользователь = ...;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Разберем вопрос о том, нужно ли добавлять общий модуль в расширение. Как правильно заметили в обсуждении, если вы не меняете код модуля, добавлять его в расширение не нужно. Расширение по умолчанию «видит» все публичные методы модулей основной конфигурации.
Однако, если вы по ошибке добавили модуль в расширение, создается «клон». Если этот клон пустой или в нем не настроены флаги Сервер / Внешнее соединение, то HTTP-сервис, приоритетно работающий с объектами расширения, попытается обратиться к этому «клону» и потерпит неудачу.
Рекомендация: Удалите общий модуль из расширения, если вы не планируете использовать аннотации &Вместо, &Перед или &После для изменения его логики. Для автоматической проверки структуры конфигурации и корректности вызовов можно использовать инструмент для анализа состава расширений и ошибок вызова модулей.
Пользователь, под которым выполняется HTTP-запрос (указанный в настройках публикации или переданный через Basic Auth), должен иметь права на выполнение методов этого общего модуля.
Важный нюанс расширений: иногда права основной конфигурации не подхватываются автоматически в контексте расширения. Проверьте, что в расширении создана или заимствована роль, дающая право на «Просмотр» и «Использование» данного модуля, и эта роль назначена пользователю.
Иногда «ошибка инициализации» — это ложный след, вызванный тем, что отладчик не может подключиться к фоновому заданию или сеансу HTTP-сервиса. Рассмотрим, как правильно настроить отладку:
-debug.ЗаписьЖурналаРегистрации для отслеживания момента падения, если отладчик не останавливается на точке останова.Посмотрим на пример отладочного вызова, который поможет локализовать место ошибки в инициализации:
Попытка
Данные = ОбщегоНазначения.ПолучитьДанныеПользователя();
Исключение
ЗаписьЖурналаРегистрации("Ошибка.HTTPСервис",
УровеньЖурналаРегистрации.Ошибка, , ,
ОписаниеОшибки());
ВызватьИсключение;
КонецПопытки;
Подводя итог, если ваш HTTP-сервис в расширении «не видит» модуль или выдает ошибку инициализации, пройдите по следующему чек-листу:
Предупреждение, Вопрос и т.д.).Следуя этим шагам, вы устраните причину сбоя и обеспечите стабильную работу ваших интеграционных шлюзов.