Как правильно прерывать операции в 1С: выбираем между Отказ = Истина и ВызватьИсключение

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

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

Рассмотрим подробнее каждый из подходов, проанализируем их сильные и слабые стороны, а также разберем ситуации, в которых один метод предпочтительнее другого.

Механизм Отказ = Истина: мягкое прерывание и работа с интерфейсом

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

Разберем основные преимущества этого метода:

  1. Дружелюбность к пользователю. Это критически важный аспект. Согласно стандартам разработки «1С», использование Отказ = Истина в сочетании с объектом СообщениеПользователю позволяет вывести список всех ошибок сразу. Если у документа не заполнены три реквизита, мы можем проверить их все, сформировать три сообщения и в конце установить Отказ = Истина. Пользователь увидит все замечания одновременно, исправит их и сохранит документ.
  2. Привязка сообщения к полю формы. Только используя СообщениеПользователю, мы можем указать свойство Поле. В этом случае на форме 1С некорректно заполненное поле подсветится красным, а сообщение станет «кликабельным» — при нажатии на него курсор автоматически переместится в нужное место.
  3. Предсказуемость в групповых обработках. Если мы пишем код для массового перепроведения документов, использование Отказ = Истина позволяет нам зафиксировать ошибку для одного объекта и спокойно перейти к обработке следующего, не прерывая весь процесс работы алгоритма.

Проанализируем пример кода в обработчике ПередЗаписью:


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

    // Если Отказ стал Истина, выполнение кода продолжится, 
    // но по завершении процедуры платформа отменит транзакцию записи.
КонецПроцедуры

Механизм ВызватьИсключение: жесткая остановка и системные ошибки

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

Выясним причины, по которым этот метод считается «агрессивным» для бизнес-логики:

Однако существуют ситуации, где ВызватьИсключение — это единственный правильный выбор:

  1. Критические технические сбои. Например, если нарушена структура данных, отсутствует соединение с внешней базой или произошла ошибка, при которой дальнейшее выполнение кода опасно (может привести к порче данных).
  2. Фоновые задания и API. В фоновых заданиях объект СообщениеПользователю может не дойти до клиента. Использование ВызватьИсключение гарантирует, что задание перейдет в статус «Ошибочно», а текст ошибки будет записан в Журнал регистрации.
  3. Web-сервисы (SOAP/HTTP). Исключение — это стандартный способ передать код ошибки (500 Internal Server Error) и описание проблемы вызывающей стороне.

Влияние на транзакции: подводные камни

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

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

Посмотрим на пример неправильной обработки:


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

В случае с Отказ = Истина такой проблемы не возникает. Платформа сама корректно и «чисто» откатит транзакцию после завершения кода процедуры, не оставляя систему в неопределенном состоянии.

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

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

Что касается логирования, то здесь есть преимущество у ВызватьИсключение: такие события автоматически попадают в Журнал регистрации с уровнем «Ошибка». Для событий типа Отказ = Истина разработчик должен самостоятельно прописывать вызов ЗаписатьСобытиеВЖурналРегистрации(), если он хочет видеть историю отказов в админ-панели.

Резюме: что и когда использовать?

Подводя итог, разделим зоны ответственности между этими двумя механизмами:

Используйте Отказ = Истина, если:

Используйте ВызватьИсключение, если:

Помните, что качественный код в 1С — это не только правильные алгоритмы, но и забота о пользователе, который должен получать понятную и наглядную обратную связь от системы.

← На главную