Как записывать и получать сообщения и ошибки из фоновых заданий в 1С

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

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

1. Механизм буферизации сообщений в фоновых заданиях

Когда мы работаем в обычном сеансе, вызов стандартного метода Сообщить() мгновенно отображает текст в окне сообщений пользователя. В фоновом задании этот процесс протекает принципиально иначе. Так как у фонового процесса нет активного окна и непосредственного интерфейса связи с пользователем, платформа автоматически перенаправляет поток сообщений во внутренний временный буфер конкретного фонового задания.

Давайте разберем по шагам, как это работает:

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

Рассмотрим пример кода, выполняющегося на сервере в рамках фонового задания, где мы фиксируем этапы процесса:


Процедура ВыполнитьДлительныйРасчет() Экспорт
    // Фиксируем этапы выполнения операции в буфере фонового задания
    Сообщить("Этап 1: Подготовка исходных данных...");
    // [Код обработки данных]
    
    Сообщить("Этап 2: Выполнение математических расчетов...");
    // [Код расчетов]
    
    Сообщить("Этап 3: Запись результатов в базу данных...");
    // [Код записи]
    
    Сообщить("Расчет успешно завершен!");
КонецПроцедуры

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

Проанализируем пример функции, которая опрашивает состояние активного фонового задания по его уникальному идентификатору (УИД) и извлекает накопленные сообщения:


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

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

2. Обработка исключений и вывод ошибок (Поле «Ошибка»)

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

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

Разберем по шагам, как правильно обработать локальную ошибку и пробросить ее наверх, чтобы она попала в поле «Ошибка» фонового задания:


Процедура ЗагрузитьДанныеИзФайла(ПутьКФайлу) Экспорт
    Файл = Новый Файл(ПутьКФайлу);
    
    Если Не Файл.Существует() Тогда
        // Формируем понятный текст ошибки для разработчика и пользователя
        ТекстОшибки = СтрШаблон("Критическая ошибка: файл '%1' не обнаружен на сервере!", ПутьКФайлу);
        
        // Прерываем выполнение задания. Данный текст будет записан в свойства задания
        ВызватьИсключение ТекстОшибки;
    КонецЕсли;
    
    // Продолжение алгоритма загрузки...
КонецПроцедуры

При вызове оператора ВызватьИсключение выполнение фонового задания прекращается, и переданная строка записывается в системные свойства задания на сервере.

3. Ловушка сериализации: работа с объектом ИнформацияОбОшибке

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

Внимание: Этот системный объект не поддерживает сериализацию! Если вы попытаетесь передать его напрямую в структуре с сервера на клиент (например, при асинхронном опросе состояния задания из формы), платформа выдаст критическую ошибку выполнения: «Ошибка отображения типов. Отсутствует отображение для типа ИнформацияОбОшибке».

Чтобы безопасно передать сведения о падении фонового задания на клиент, необходимо преобразовать информацию об ошибке в обычную строку еще на стороне сервера. Для этого используются встроенные платформенные функции КраткоеПредставлениеОшибки() и ПодробноеПредставлениеОшибки().

Посмотрим на пример безопасного извлечения ошибки фонового задания:


&НаСервереБезКонтекста
Функция ПолучитьПодробнуюОшибкуЗадания(ИдентификаторЗадания)
    Задание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ИдентификаторЗадания);
    
    Если Задание <> Неопределено И Задание.Состояние = СостояниеФоновогоЗадания.ЗавершеноАварийно Тогда
        // Проверяем наличие информации об ошибке
        Если Задание.ИнформацияОбОшибке <> Неопределено Тогда
            // Преобразуем объект ИнформацияОбОшибке в строку со стеком вызовов
            Возврат ПодробноеПредставлениеОшибки(Задание.ИнформацияОбОшибке);
        КонецЕсли;
    КонецЕсли;
    
    Возврат "";
КонецФункции

4. Специфика сообщений в среде БСП (Библиотека стандартных подсистем)

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

Такие технологические сообщения отправляются в буфер в виде строк специального формата, например: {"Progress":45}. Если считывать сообщения напрямую стандартными средствами платформы 1С, эти технологические пакеты смешаются с вашими прикладными сообщениями Сообщить().

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


// Используем метод подсистемы ДлительныеОперации для получения сообщений.
// Он автоматически отфильтрует и скроет служебные пакеты прогресса БСП.
МассивСообщений = ДлительныеОперации.СообщенияПользователю(Истина, ИдентификаторЗадания);

5. Как сообщения и ошибки отображаются в «Инструментах разработчика» (ИР)

Многие разработчики используют популярный программный комплекс «Инструменты разработчика» (ИР) для администрирования и отладки прикладных решений. Консоль заданий в составе ИР существенно упрощает разбор полетов при работе с фоновыми процессами:

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

← На главную