Разработка и Конфигурация · 9 мин
Как вывести ошибку в исключении 1С
Как вывести текст ошибки в исключении 1С: конструкция Попытка–Исключение, ОписаниеОшибки(), Сообщить и ВызватьИсключение. Примеры кода и типичные ошибки.
Когда код 1С падает с ошибкой, пользователь видит стандартное системное окно, а разработчику нужно понять, что именно пошло не так. Платформа «1С:Предприятие» даёт для этого встроенный механизм: конструкцию Попытка ... Исключение ... КонецПопытки и функцию ОписаниеОшибки(), которая возвращает текст возникшей ошибки. Умение правильно перехватить и вывести исключение — базовый навык для отладки обменов, запросов, проведения документов и фоновых заданий.
Вывести ошибку можно несколькими способами: показать пользователю через Сообщить() или ПоказатьПредупреждение(), записать в журнал регистрации через ЗаписьЖурналаРегистрации(), вернуть текст наружу через ВызватьИсключение. Выбор зависит от того, кто должен увидеть сообщение — конечный пользователь, администратор или вызывающий код.
Как устроен механизм исключений в 1С
Исключение в 1С — это аварийное прерывание выполнения кода. Оно возникает при обращении к несуществующему реквизиту, делении на ноль, ошибке запроса, недоступности файла или веб-сервиса. Если исключение не перехвачено, платформа показывает системное окно с техническим описанием и прекращает выполнение текущего обработчика.
Конструкция Попытка ... Исключение ... КонецПопытки позволяет перехватить такое прерывание. Код внутри блока Попытка выполняется как обычно; как только возникает ошибка, управление переходит в блок Исключение, где доступна информация о случившемся через функцию ОписаниеОшибки().
Вывод текста ошибки через ОписаниеОшибки()
Функция ОписаниеОшибки() работает только внутри блока Исключение и возвращает строку с текстом ошибки. Самый простой способ показать её пользователю — вывести через Сообщить(), тогда текст появится в панели сообщений.
Попытка
Результат = Значение / Делитель;
Исключение
Сообщить("Ошибка расчёта: " + ОписаниеОшибки());
КонецПопытки;
Для управляемых форм диалоговое окно удобнее показать через ПоказатьПредупреждение(), потому что Сообщить() легко пропустить среди других сообщений. В серверных процедурах и фоновых заданиях, где нет интерфейса, основным приёмником текста ошибки должен быть журнал регистрации.
Попытка
ВыполнитьОбменДанными();
Исключение
ЗаписьЖурналаРегистрации("Обмен данными", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки());
КонецПопытки;Запись ошибки в журнал регистрации
Журнал регистрации — правильное место для текстов ошибок, которые не должны потеряться. Метод ЗаписьЖурналаРегистрации() принимает имя события, уровень важности, объект метаданных, данные и комментарий. В комментарий и передают результат ОписаниеОшибки().
Используйте уровень УровеньЖурналаРегистрации.Ошибка, чтобы потом быстро отфильтровать проблемные записи. В имя события добавляйте понятный префикс — например, «Обмен с сайтом» или «Проведение документа»: это сильно упрощает поиск в журнале при разборе инцидента.
- 1Оберните проблемный фрагмент в Попытка...Исключение...КонецПопытки
- 2В блоке Исключение получите текст через ОписаниеОшибки()
- 3Запишите текст в журнал регистрации с уровнем Ошибка и понятным именем события
- 4При необходимости дополнительно сообщите пользователю через Сообщить() или ПоказатьПредупреждение()
- 5Откройте журнал регистрации и проверьте, что запись появилась с нужным текстом
Проброс ошибки наружу через ВызватьИсключение
Иногда обработать ошибку на текущем уровне нельзя — её должен увидеть вызывающий код. Тогда в блоке Исключение вызывают ВызватьИсключение, который создаёт новое исключение с заданным текстом. Так можно заменить непонятное системное сообщение вроде «Ошибка при вызове метода контекста» на осмысленное «Не удалось загрузить курсы валют: сервис недоступен».
Попытка
ЗагрузитьКурсыВалют();
Исключение
ВызватьИсключение "Не удалось загрузить курсы валют: " + ОписаниеОшибки();
КонецПопытки;
Важно не потерять исходный текст: добавляйте ОписаниеОшибки() к своему сообщению, иначе диагностика первопричины станет невозможной. Пустой ВызватьИсключение без параметров пробрасывает текущее исключение дальше без изменений — это полезно, когда текст уже достаточно информативен.
Подробное описание ошибки через ИнформацияОбОшибке()
Функция ОписаниеОшибки() возвращает только краткий текст. Когда нужны детали — имя модуля, строка кода, вложенная причина — используйте ИнформацияОбОшибке(). Она возвращает объект со свойствами Описание, ИмяМодуля, НомерСтроки, ИсходнаяСтрока и Причина (вложенная ошибка).
Попытка
ВыполнитьОперацию();
Исключение
Инфо = ИнформацияОбОшибке();
ТекстОшибки = Инфо.Описание + " (модуль: " + Инфо.ИмяМодуля
+ ", строка " + Инфо.НомерСтроки + ")";
ЗаписьЖурналаРегистрации("Операция", УровеньЖурналаРегистрации.Ошибка, , , ТекстОшибки);
КонецПопытки;
Такой подход особенно ценен при отладке длинных цепочек вызовов и обменов: вы видите не только «что сломалось», но и «где именно». Свойство Причина позволяет развернуть всю цепочку вложенных ошибок, если их было несколько.
Исключения в транзакциях и типичные ошибки
Если исключение возникло внутри транзакции (НачатьТранзакцию()), её обязательно нужно откатить через ОтменитьТранзакцию() в блоке Исключение. Иначе транзакция останется незавершённой, а это приводит к блокировкам и ошибкам «Транзакция не активна» при последующих обращениях к базе.
НачатьТранзакцию();
Попытка
ЗаписатьОбъекты();
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ЗаписьЖурналаРегистрации("Запись данных", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки());
ВызватьИсключение;
КонецПопытки;
Как проверить, что обработка ошибки работает
Проверку делайте намеренным вызовом ошибки: подставьте несуществующий файл, неверный запрос или деление на ноль. Убедитесь, что текст попадает туда, куда задумано: в панель сообщений, в диалог предупреждения или в журнал регистрации с правильным именем события и уровнем «Ошибка».
Как проверить результат
Есть запись с уровнем Ошибка, понятным событием и полным текстом
Записи нет или текст обрезан/пуст
Пользователь видит понятное описание проблемы
Системное окно с техническим текстом или полная тишина
После ошибки база доступна, блокировок нет
Ошибка «Транзакция не активна» или зависшие сеансы
FAQ
Чем ОписаниеОшибки() отличается от ИнформацияОбОшибке()?
ОписаниеОшибки() возвращает только строку с кратким текстом. ИнформацияОбОшибке() возвращает объект с деталями: именем модуля, номером строки, исходной строкой кода и вложенной причиной ошибки. Для быстрого сообщения достаточно первого, для диагностики и логирования лучше второе.
Почему ОписаниеОшибки() возвращает пустую строку?
Функция работает только внутри блока Исключение. Если вызвать её в обычном коде или после КонецПопытки, она вернёт пустую строку. Также проверьте, что ошибка действительно возникла внутри Попытка, а не до неё.
Что лучше использовать: Сообщить() или ПоказатьПредупреждение()?
Сообщить() выводит текст в панель сообщений и подходит для некритичных уведомлений и клиент-серверных вызовов. ПоказатьПредупреждение() открывает модальное окно, которое пользователь точно увидит — используйте его для критических ошибок в управляемых формах. В серверном коде без интерфейса оба варианта заменяет запись в журнал регистрации.
Как пробросить исключение наверх, не теряя исходный текст?
Либо вызовите ВызватьИсключение без параметров — тогда текущее исключение уйдёт дальше как есть, либо сформируйте новый текст, добавив к нему ОписаниеОшибки(). Никогда не заменяйте текст полностью своим, не включив первопричину.
Нужно ли оборачивать в Попытку весь код подряд?
Нет. Оборачивайте только фрагменты, где ошибка ожидаема и вы знаете, что с ней делать: обращения к файлам, сети, внешним сервисам, запросы, транзакции. Глобальная Попытка вокруг всего модуля маскирует дефекты и мешает отладке.
Как увидеть ошибку фонового задания?
Текст ошибки фонового задания виден в журнале регистрации (если вы записали его через ЗаписьЖурналаРегистрации) и в консоли заданий — в свойствах фонового задания хранится информация об ошибке. Поэтому в обработчике фонового задания блок Исключение с записью в журнал обязателен.
Что важно запомнить
Перехватывайте ошибки через Попытка...Исключение, получайте текст через ОписаниеОшибки() или ИнформацияОбОшибке(), выводите пользователю через Сообщить/ПоказатьПредупреждение и обязательно записывайте в журнал регистрации. В транзакциях не забывайте ОтменитьТранзакцию(), а при пробросе наружу сохраняйте исходный текст ошибки.