К статье
Практический материал

Разработка и Конфигурация · 9 мин

Как вывести ошибку в исключении 1С

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

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

Вывести ошибку можно несколькими способами: показать пользователю через Сообщить() или ПоказатьПредупреждение(), записать в журнал регистрации через ЗаписьЖурналаРегистрации(), вернуть текст наружу через ВызватьИсключение. Выбор зависит от того, кто должен увидеть сообщение — конечный пользователь, администратор или вызывающий код.

Как устроен механизм исключений в 1С

Исключение в 1С — это аварийное прерывание выполнения кода. Оно возникает при обращении к несуществующему реквизиту, делении на ноль, ошибке запроса, недоступности файла или веб-сервиса. Если исключение не перехвачено, платформа показывает системное окно с техническим описанием и прекращает выполнение текущего обработчика.

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

Вывод текста ошибки через ОписаниеОшибки()

Функция ОписаниеОшибки() работает только внутри блока Исключение и возвращает строку с текстом ошибки. Самый простой способ показать её пользователю — вывести через Сообщить(), тогда текст появится в панели сообщений.

Попытка

Результат = Значение / Делитель;

Исключение

Сообщить("Ошибка расчёта: " + ОписаниеОшибки());

КонецПопытки;

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

bsl
Попытка
	ВыполнитьОбменДанными();
Исключение
	ЗаписьЖурналаРегистрации("Обмен данными", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки());
КонецПопытки;

Запись ошибки в журнал регистрации

Журнал регистрации — правильное место для текстов ошибок, которые не должны потеряться. Метод ЗаписьЖурналаРегистрации() принимает имя события, уровень важности, объект метаданных, данные и комментарий. В комментарий и передают результат ОписаниеОшибки().

Используйте уровень УровеньЖурналаРегистрации.Ошибка, чтобы потом быстро отфильтровать проблемные записи. В имя события добавляйте понятный префикс — например, «Обмен с сайтом» или «Проведение документа»: это сильно упрощает поиск в журнале при разборе инцидента.

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

Проброс ошибки наружу через ВызватьИсключение

Иногда обработать ошибку на текущем уровне нельзя — её должен увидеть вызывающий код. Тогда в блоке Исключение вызывают ВызватьИсключение, который создаёт новое исключение с заданным текстом. Так можно заменить непонятное системное сообщение вроде «Ошибка при вызове метода контекста» на осмысленное «Не удалось загрузить курсы валют: сервис недоступен».

Попытка

ЗагрузитьКурсыВалют();

Исключение

ВызватьИсключение "Не удалось загрузить курсы валют: " + ОписаниеОшибки();

КонецПопытки;

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

Подробное описание ошибки через ИнформацияОбОшибке()

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

Попытка

ВыполнитьОперацию();

Исключение

Инфо = ИнформацияОбОшибке();

ТекстОшибки = Инфо.Описание + " (модуль: " + Инфо.ИмяМодуля

+ ", строка " + Инфо.НомерСтроки + ")";

ЗаписьЖурналаРегистрации("Операция", УровеньЖурналаРегистрации.Ошибка, , , ТекстОшибки);

КонецПопытки;

Такой подход особенно ценен при отладке длинных цепочек вызовов и обменов: вы видите не только «что сломалось», но и «где именно». Свойство Причина позволяет развернуть всю цепочку вложенных ошибок, если их было несколько.

Исключения в транзакциях и типичные ошибки

Если исключение возникло внутри транзакции (НачатьТранзакцию()), её обязательно нужно откатить через ОтменитьТранзакцию() в блоке Исключение. Иначе транзакция останется незавершённой, а это приводит к блокировкам и ошибкам «Транзакция не активна» при последующих обращениях к базе.

НачатьТранзакцию();

Попытка

ЗаписатьОбъекты();

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();

ЗаписьЖурналаРегистрации("Запись данных", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки());

ВызватьИсключение;

КонецПопытки;

Типичные ошибки
01
Пустой блок Исключение — ошибка проглатывается, диагностика невозможна
02
ОписаниеОшибки() вне блока Исключение — функция вернёт пустую строку
03
Потеря исходного текста при ВызватьИсключение — заменяйте текст, добавляя ОписаниеОшибки(), а не вместо него
04
Отсутствие ОтменитьТранзакцию() при ошибке в транзакции — блокировки и сбои базы
05
Только Сообщить() в серверном коде — пользователь сообщение не увидит, нужен журнал регистрации

Как проверить, что обработка ошибки работает

Проверку делайте намеренным вызовом ошибки: подставьте несуществующий файл, неверный запрос или деление на ноль. Убедитесь, что текст попадает туда, куда задумано: в панель сообщений, в диалог предупреждения или в журнал регистрации с правильным именем события и уровнем «Ошибка».

Контрольные точки

Как проверить результат

Текст в журнале регистрации
Норма

Есть запись с уровнем Ошибка, понятным событием и полным текстом

Тревожный признак

Записи нет или текст обрезан/пуст

Сообщение пользователю
Норма

Пользователь видит понятное описание проблемы

Тревожный признак

Системное окно с техническим текстом или полная тишина

Поведение транзакции
Норма

После ошибки база доступна, блокировок нет

Тревожный признак

Ошибка «Транзакция не активна» или зависшие сеансы

FAQ

Чем ОписаниеОшибки() отличается от ИнформацияОбОшибке()?

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

Почему ОписаниеОшибки() возвращает пустую строку?

Функция работает только внутри блока Исключение. Если вызвать её в обычном коде или после КонецПопытки, она вернёт пустую строку. Также проверьте, что ошибка действительно возникла внутри Попытка, а не до неё.

Что лучше использовать: Сообщить() или ПоказатьПредупреждение()?

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

Как пробросить исключение наверх, не теряя исходный текст?

Либо вызовите ВызватьИсключение без параметров — тогда текущее исключение уйдёт дальше как есть, либо сформируйте новый текст, добавив к нему ОписаниеОшибки(). Никогда не заменяйте текст полностью своим, не включив первопричину.

Нужно ли оборачивать в Попытку весь код подряд?

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

Как увидеть ошибку фонового задания?

Текст ошибки фонового задания виден в журнале регистрации (если вы записали его через ЗаписьЖурналаРегистрации) и в консоли заданий — в свойствах фонового задания хранится информация об ошибке. Поэтому в обработчике фонового задания блок Исключение с записью в журнал обязателен.

Итог

Что важно запомнить

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