Как вызвать исключение со своим текстом ошибки в 1С:Предприятие?

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

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

Выясним причину такого поведения и рассмотрим способы передачи детального текста ошибки выше по стеку вызовов.

Почему стандартный текст Сообщить() не попадает в ОписаниеОшибки()?

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

Способ 1. Использование оператора ВызватьИсключение с параметром

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

Посмотрим на пример генерации исключения внутри обработчика или подписки на событие:


Если НарушенаДатаЗапрета Тогда
    ТекстСообщения = "Ошибка при проведении: нарушена дата запрета на проведение документа по причине...";
    ВызватьИсключение ТекстСообщения;
КонецЕсли;

Разберем различия в формах вызова этого оператора:

  1. ВызватьИсключение <Выражение>; — создает новое исключение с переданным текстом. Работает в любом модуле и процедуре. Скобки вокруг выражения не являются обязательными, но допустимы: ВызватьИсключение(ТекстСообщения);.
  2. ВызватьИсключение; (без параметров) — используется исключительно внутри блока Исключение ... КонецПопытки для повторного проброса ранее пойманной ошибки вверх по стеку.

Теперь посмотрим, как перехватить эту ошибку в вызывающем коде:


Попытка
    ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
Исключение
    // Получаем переданный текст ошибки
    ТекстОшибки = ОписаниеОшибки();
    
    // Для более точного анализа в современных версиях платформы:
    ИнформацияОбОшибке = ИнформацияОбОшибке();
    ТекстОшибкиКраткий = КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
КонецПопытки;

Способ 2. Программное чтение буфера сообщений без принудительного исключения

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

Если документ отменяет проведение через Отказ = Истина, в вызывающем коде можно извлечь все накопленные сообщения через метод ПолучитьСообщенияПользователю():


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

Рекомендации и ограничения при использовании ВызватьИсключение

  1. Прерывание выполнения: оператор ВызватьИсключение останавливает выполнение текущего метода мгновенно. Если требуется проверить несколько условий и показать пользователю полный перечень замечаний, следует использовать СообщениеПользователю и флаг Отказ.
  2. Транзакции: возникновение исключения внутри открытой транзакции переводит её в состояние ошибки. Зафиксировать такую транзакцию после перехвата исключения уже невозможно — доступен только откат.
  3. Получение стека ошибок: для логирования и анализа ошибок рекомендуется использовать функцию ИнформацияОбОшибке() и методы ПодробноеПредставлениеОшибки() или КраткоеПредставлениеОшибки(), что позволяет избавиться от системных оберток платформы.
← На главную