Как правильно вызвать процедуру общего модуля из веб-сервиса 1С и почему вылетает отладка?

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

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

Анализируем причину: Почему «вылетает» отладка?

Проанализируем поведение системы в момент обращения к веб-сервису. Веб-сервис всегда исполняется на стороне сервера в неинтерактивном режиме. Когда код доходит до точки вызова ОбщийМодульКлиент.ОтправитьСообщение, сервер 1С должен скомпилировать этот модуль для текущего контекста исполнения. Если в модуле присутствуют ошибки компиляции, выполнение прерывается мгновенно.

Основная ошибка заключается в том, что разработчики пытаются вызвать код, который физически не может существовать на сервере. Рассмотрим подробнее, что происходит при попытке просто «поставить галочки» Сервер, Клиент и Внешнее соединение в свойствах общего модуля. Если внутри модуля содержатся методы, доступные только в интерфейсе (например, Предупреждение(), Вопрос(), ПоказатьОповещениеПользователя()), то при попытке сервера скомпилировать этот модуль возникнет критическая ошибка. Сервер «не знает», что такое диалоговое окно, и компиляция всего модуля целиком завершается неудачей еще до того, как начнет выполняться ваша конкретная процедура.

Разберем правила компиляции общих модулей

Выясним важный нюанс: нельзя просто так смешивать клиентский и серверный контекст. Посмотрим на основные правила:

  1. Контекстная несовместимость: С сервера (где работает веб-сервис) нельзя вызвать клиентскую процедуру ни при каких обстоятельствах. Это фундаментальное ограничение архитектуры «клиент-сервер».
  2. Целостность модуля: Общий модуль (если он не глобальный) компилируется в момент первого обращения к нему. Если в любой части модуля есть код, недопустимый для сервера, весь модуль станет недоступен для серверного вызова.
  3. Инструкции препроцессора: Чтобы один и тот же модуль мог работать и на клиенте, и на сервере, интерактивные методы должны быть обрамлены специальными директивами.

Проанализируем пример использования директив препроцессора, которые позволяют «спрятать» клиентский код от сервера:


#Если Клиент Тогда
Процедура ПоказатьДиалог()
    Предупреждение("Сообщение для пользователя");
КонецПроцедуры
#КонецЕсли

В этом случае сервер при компиляции просто проигнорирует блок между #Если Клиент и #КонецЕсли, и модуль будет успешно загружен в серверную память.

Решение проблемы: Правильная организация кода для веб-сервиса

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

Шаг 1. Создание серверного общего модуля

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

Шаг 2. Перенос логики отправки

Посмотрим на пример кода, который будет стабильно работать в контексте веб-сервиса. Помните, что на сервере нельзя использовать почтовые клиенты (COM-объекты Outlook и подобные). Нужно использовать исключительно объект ИнтернетПочта.


// В модуле РаботаСПочтойСервер
Процедура ОтправитьПисьмоНаСервере(ПараметрыСообщения, Состояние) Экспорт
    
    // Подготавливаем структуру сообщения
    Письмо = Новый ИнтернетПочтовоеСообщение;
    Письмо.Тема = "Уведомление по заявке: " + ПараметрыСообщения.Обращение;
    Письмо.Тексты.Добавить(ПараметрыСообщения.ПричинаВозвратаВработу);
    
    // Здесь должна быть логика настройки профиля и отправки через ИнтернетПочта
    // ...
    
    ЗаписьЖурналаРегистрации("ОтправкаПочты", УровеньЖурналаРегистрации.Информационный, , , "Письмо отправлено для ID: " + ПараметрыСообщения.УникальныйИдентификатор);
    
КонецПроцедуры

Шаг 3. Вызов из метода веб-сервиса

Теперь в теле метода вашего веб-сервиса обращение будет выглядеть следующим образом:


Процедура ВыполнитьЗапросВебСервиса(Данные)
    
    ПараметрыСообщения = Новый Структура;
    ПараметрыСообщения.Вставить("УникальныйИдентификатор", Данные.id);
    ПараметрыСообщения.Вставить("Обращение", Данные.Заявка);
    ПараметрыСообщения.Вставить("ПричинаВозвратаВработу", Данные.Комментарий);
    
    Попытка
        // Вызываем именно серверный модуль
        РаботаСПочтойСервер.ОтправитьПисьмоНаСервере(ПараметрыСообщения, Данные.Состояние);
    Исключение
        // Обязательно фиксируем ошибку в Журнале Регистрации, 
        // так как в веб-сервисе пользователь не увидит сообщение об ошибке
        ЗаписьЖурналаРегистрации("ОшибкаВебСервиса", 
            УровеньЖурналаРегистрации.Ошибка, , , 
            ОписаниеОшибки());
    КонецПопытки;
    
КонецПроцедуры

Важные рекомендации по отладке веб-сервисов

Если отладка все же «вылетает», проанализируем настройки вашего сервера. Отладка веб-сервисов имеет свои особенности:

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

← На главную