Как сообщить пользователю об ошибке при вызове серверного метода в дополнительной обработке?

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

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

Причина возникновения проблемы

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

Способ 1. Настройка параметров ожидания длительной операции

В современных версиях БСП запуск серверных методов обработок осуществляется через общую форму ДополнительныеОтчетыИОбработки. Чтобы сообщения из фонового задания начали отображаться, необходимо убедиться, что в параметрах ожидания установлен соответствующий флаг. Выясним, как это реализовать через расширение формы.

Рассмотрим пример перехвата процедуры запуска команды в расширении формы:


&Вместо("ВыполнитьСерверныйМетодОбработки")
&НаКлиенте
Процедура ИмяРасширения_ВыполнитьСерверныйМетодОбработки()
    
    // Запускаем стандартный механизм формирования фонового задания
    Задание = ЗапуститьФоновоеЗадание(ВыполняемаяКоманда, УникальныйИдентификатор);
    
    // Настраиваем параметры ожидания завершения
    НастройкиОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
    
    // Указываем системе, что нужно выводить окно ожидания (прогресс-бар)
    НастройкиОжидания.ВыводитьОкноОжидания = Истина;
    
    // КРИТИЧЕСКИ ВАЖНО: устанавливаем флаг вывода сообщений
    НастройкиОжидания.ВыводитьСообщения = Истина;
    
    // Устанавливаем обработчик завершения
    Обработчик = Новый ОписаниеОповещения("ВыполнитьСерверныйМетодОбработкиЗавершение", ЭтотОбъект);
    ДлительныеОперацииКлиент.ОжидатьЗавершение(Задание, Обработчик, НастройкиОжидания);
    
КонецПроцедуры

Способ 2. Привязка сообщений через ИдентификаторНазначения

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

Посмотрим на пример кода, который позволяет программно «привязать» сообщения к форме владельца (например, к списку документов, из которого была нажата кнопка):


&Вместо("ВыполнитьСерверныйМетодОбработкиЗавершение")
&НаКлиенте
Процедура ИмяРасширения_ВыполнитьСерверныйМетодОбработкиЗавершение(Задание, ДополнительныеПараметры) Экспорт
    
    Если Задание = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Проверяем статус выполнения
    Если Задание.Статус = "Выполнено" Тогда
        
        // Если в задании накопились сообщения, выведем их
        Если Задание.Сообщения.Количество() > 0 Тогда
            Для Каждого Сообщ Из Задание.Сообщения Цикл
                // Привязываем сообщение к идентификатору формы-владельца
                // Это заставит систему показать сообщение в текущем интерфейсе
                Сообщ.ИдентификаторНазначения = ВладелецФормы.УникальныйИдентификатор;
                Сообщ.Сообщить();
            КонецЦикла;    
        КонецЕсли;
        
        // Показываем стандартное оповещение
        Если ВыполняемаяКоманда.ПоказыватьОповещение Тогда
            ПоказатьОповещениеПользователя(НСтр("ru = 'Команда выполнена'"),, ВыполняемаяКоманда.Представление);
        КонецЕсли;
        
    ИначеЕсли Задание.Статус = "Ошибка" Тогда
        // Обработка критических ошибок фонового задания
        ВызватьИсключение Задание.КраткоеПредставлениеОшибки;
    КонецЕсли;
    
    // Закрываем форму обработки, если она открыта
    Если Открыта() Тогда
        Закрыть();
    КонецЕсли;
    
КонецПроцедуры

Способ 3. Передача структурированного результата через временное хранилище

Для сложных обменов данными (как в случае с OData) простого текстового сообщения часто недостаточно. Рассмотрим более продвинутый подход: передачу структуры данных из фонового задания.

  1. В серверном модуле обработки: Вместо Сообщить() формируйте структуру или таблицу с результатами. Поместите её во временное хранилище, адрес которого передается в ДлительныеОперации.ЗаписатьРезультат.
  2. На клиенте: В процедуре завершения получите эти данные методом ПолучитьИзВременногоХранилища(Задание.АдресРезультата).

Разберем, почему это удобно: вы можете передать массив структур, содержащий GUID созданных объектов, тексты конкретных ошибок OData-запросов и статистику. На клиенте эти данные можно вывести не просто в окно сообщений, а открыть специальную форму протокола обмена.

Особенности работы с Исключениями

Важно помнить, что если в вашем серверном методе произойдет необработанное исключение (ВызватьИсключение), фоновое задание прервется со статусом «Ошибка». Текст этой ошибки будет доступен в свойстве Задание.ПодробноеПредставлениеОшибки.

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

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

Использование системы взаимодействия и логов

Для очень длительных процессов (десятки минут или часы) рассмотренные методы могут быть неудобны, так как пользователь может закрыть сеанс или переключиться на другую задачу. В таких сценариях эффективнее использовать:

Выясним итог: для быстрых команд «Вызова серверного метода» оптимальным является сочетание настройки НастройкиОжидания.ВыводитьСообщения = Истина и программного контроля Сообщ.ИдентификаторНазначения в процедуре обратного вызова.

← На главную