Разработка и Конфигурация · 12 мин
Как сообщить пользователю об ошибке в 1С
Способы вывода ошибок пользователю в 1С: СообщитьПользователю, ВызватьИсключение, ПоказатьПредупреждение. Примеры кода, отличия методов и типичные ошибки.
Правильное информирование пользователя об ошибке — одна из базовых задач при разработке на платформе 1С:Предприятие. От того, каким способом выведено сообщение, зависит, поймёт ли пользователь, что произошло, сможет ли исправить ситуацию и не прервётся ли важная бизнес-операция на середине.
Во встроенном языке 1С есть несколько принципиально разных механизмов: мягкие сообщения через объект СообщениеПользователю, прерывание выполнения через ВызватьИсключение, модальные и немодальные диалоги ПоказатьПредупреждение и ПоказатьВопрос, а также оповещения через ПоказатьОповещениеПользователя. Каждый из них решает свою задачу, и смешивать их бездумно — типичная ошибка начинающих разработчиков.
Ниже разобраны основные способы, их отличия, примеры кода и критерии выбора. Отдельно рассмотрены тонкости серверного контекста, транзакций и типичные ошибки при выводе сообщений.
Какие механизмы вывода ошибок есть в 1С
Платформа предлагает четыре основных подхода, различающихся по силе воздействия на выполнение кода и по месту отображения.
Первый — СообщитьПользователю (и устаревший вариант Сообщить). Сообщение попадает в панель сообщений формы или в окно сообщений, не прерывает выполнение кода и может быть привязано к конкретному полю формы. Это стандартный способ показать ошибки заполнения при проведении документа или записи элемента.
Второй — ВызватьИсключение. Выполнение текущего кода прекращается, транзакция (если открыта) откатывается, пользователь видит окно с текстом ошибки и технической информацией. Используется, когда продолжать работу нельзя или опасно.
Третий — интерактивные диалоги ПоказатьПредупреждение, ПоказатьВопрос, ПоказатьВводЗначения. Они работают только на клиенте и требуют асинхронного описания оповещения. Четвёртый — ПоказатьОповещениеПользователя, ненавязчивое всплывающее уведомление, не требующее реакции.
Сравнение способов
Мягкое сообщение в панели формы, можно привязать к полю. Не прерывает выполнение — отказ делайте сами через параметр Отказ.
Полная остановка кода и откат транзакции. Подходит для критических сбоев, но слишком груб для обычных ошибок заполнения.
Только клиент, только с описанием оповещения. Нужны, когда требуется подтверждение пользователя.
Информационное уведомление без блокировки. Для успешных операций и фоновых событий, не для ошибок.
Как вывести сообщение через СообщитьПользователю
Это основной способ сообщить об ошибках проверки данных. Конструкция выглядит так: создаётся объект СообщениеПользователю, заполняются его свойства, затем вызывается метод Сообщить().
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Если Не ЗначениеЗаполнено(Контрагент) Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = НСтр("ru = 'Не заполнен контрагент. Укажите контрагента перед проведением.'");
Сообщение.Поле = "Контрагент";
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Ключевые свойства: Текст — понятное описание проблемы и способа её устранения; Поле — имя реквизита, к которому привязано сообщение (платформа подсветит его в форме); УстановитьДанные() — привязка к объекту, чтобы сообщение не «потерялось» при серверном вызове.
Важно: сам по себе вызов Сообщить() не отменяет действие. Если вы проверяете данные в обработчике ОбработкаПроверкиЗаполнения или ПередЗаписью, обязательно установите параметр Отказ = Истина, иначе документ запишется с ошибкой, а сообщение останется просто текстом в панели.
Когда использовать ВызватьИсключение
Исключение — это аварийная остановка. Код после ВызватьИсключение не выполняется, незавершённая транзакция откатывается, управление возвращается на уровень выше, где ошибка либо перехватывается через Попытка...Исключение, либо показывается пользователю в виде окна «Ошибка».
Если Не РезультатЗапроса.Пустой() Тогда
ВызватьИсключение СтрШаблон(
НСтр("ru = 'Не удалось провести документ: по товару ""%1"" недостаточно остатков на складе.'"),
Выборка.Номенклатура);
КонецЕсли;
Уместные сценарии: нарушение целостности данных, сбой обмена, невозможность выполнить операцию из-за внешних условий (недоступен веб-сервис, не найден файл). Неуместные: обычная проверка заполнения реквизитов — для этого есть механизм сообщений с отказом, который даёт пользователю список всех ошибок сразу, а не останавливается на первой.
При перехвате исключения в Попытка...Исключение не «проглатывайте» его молча. Минимум — запишите подробности в журнал регистрации и выведите пользователю понятный текст через ОписаниеОшибки() или ИнформацияОбОшибке().
Как показать предупреждение и вопрос на клиенте
Методы ПоказатьПредупреждение и ПоказатьВопрос работают только в клиентском коде (директивы &НаКлиенте). В тонком клиенте и веб-клиенте они неблокирующие: результат обрабатывается через описание оповещения.
&НаКлиенте
Процедура УдалитьСтроки(Команда)
Оповещение = Новый ОписаниеОповещения("УдалитьСтрокиЗавершение", ЭтотОбъект);
ПоказатьВопрос(Оповещение,
НСтр("ru = 'Выбранные строки будут удалены без возможности восстановления. Продолжить?'"),
РежимДиалогаВопрос.ДаНет,
20,
КодВозвратаДиалога.Нет);
КонецПроцедуры
&НаКлиенте
Процедура УдалитьСтрокиЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
УдалитьСтрокиНаСервере();
КонецЕсли;
КонецПроцедуры
Обратите внимание на третий и четвёртый параметры: таймаут и кнопка по умолчанию. Для деструктивных действий кнопкой по умолчанию должна быть безопасная («Нет», «Отмена») — это защищает от случайного подтверждения по Enter.
Для простого уведомления без выбора используйте ПоказатьПредупреждение с кратким заголовком и понятным текстом. Не выводите туда технические детали стека вызовов — пользователю нужны причина и действие, а не номер строки модуля.
- 1Определите, где выполняется код: на клиенте или на сервере.
- 2Если это проверка данных при записи — используйте СообщитьПользователю с Отказ = Истина.
- 3Если продолжение невозможно и нужен откат — ВызватьИсключение с понятным текстом.
- 4Если нужна реакция пользователя — ПоказатьВопрос или ПоказатьПредупреждение с оповещением.
- 5Проверьте результат: сообщение видно, привязано к полю, действие корректно отменено или выполнено.
Особенности серверного контекста и транзакций
На сервере (&НаСервере, серверные общие модули, обработчики объектов) недоступны модальные диалоги и методы ПоказатьПредупреждение/ПоказатьВопрос — попытка вызвать их приведёт к ошибке компиляции или выполнения. Серверный код может только формировать сообщения через СообщитьПользователю либо вызывать исключения.
Сообщения, созданные на сервере в контексте формы, автоматически передаются на клиент и показываются в панели сообщений формы. Чтобы они не терялись при вызовах вне контекста формы, проверяйте, что сообщение будет доставлено: в фоновых заданиях и регламентных операциях сообщения пользователю вообще не отображаются — там нужен журнал регистрации.
Внутри транзакции сообщения лучше накапливать и выводить после ЗафиксироватьТранзакцию(), либо использовать исключение для отката. Если вывести сообщение до отката, пользователь увидит его, хотя операция фактически не выполнена, — это вводит в заблуждение.
Удобный приём: в длинных серверных алгоритмах собирайте ошибки в массив структур (поле, текст, критичность), а в конце одним проходом выводите их через СообщитьПользователю. Пользователь получает полный список проблем за один раз, а не исправляет их по одной после каждого перезапуска операции.
Как писать текст сообщения, который помогает
Хорошее сообщение об ошибке содержит три части: что произошло, почему это проблема, что сделать пользователю. Сравните: «Ошибка проведения» — бесполезно; «Документ не проведён: по товару "Кабель ВВГ 3х2.5" не хватает 5 шт. на складе "Основной". Уменьшите количество или оформите поступление» — решает проблему без обращения к программисту.
Избегайте в тексте, видимом пользователю, технических подробностей: имён процедур, кодов ошибок СУБД, фрагментов запросов. Эти данные пишите в журнал регистрации через ЗаписьЖурналаРегистрации с уровнем «Ошибка», а пользователю давайте человекочитаемое описание и, при необходимости, указание обратиться к администратору.
Тексты, подлежащие переводу, оформляйте через функцию НСтр — это требование стандартов разработки и упрощает локализацию конфигурации.
Проверка результата и границы самостоятельной работы
После внедрения механизма сообщений проверьте три вещи. Во-первых, сообщение реально отображается: в форме — в панели сообщений с подсветкой поля, вне формы — в окне сообщений. Во-вторых, поведение соответствует замыслу: при ошибке заполнения действие отменено, при исключении — транзакция откачена и данные не повреждены. В-третьих, текст понятен пользователю без пояснений разработчика — дайте его прочитать человеку, который не писал этот код.
Самостоятельная доработка безопасна, пока вы меняете только тексты и способ вывода сообщений в копии конфигурации или расширении. Вмешательство в логику транзакций, обработчики проведения типовых документов и механизмы обмена требует тестирования на копии базы: ошибка в этих местах может привести к расхождению данных или потере проведённых документов.
Как проверить результат
Текст виден в панели сообщений, поле подсвечено
Сообщение не появляется или выводится без привязки к объекту
При ошибке заполнения запись/проведение не выполняется
Объект сохраняется несмотря на сообщение об ошибке
После исключения данные в состоянии до операции
Часть изменений зафиксирована, часть откачена
Ошибка зафиксирована с подробным описанием
В журнале пусто, причину восстановить нельзя
Часто задаваемые вопросы
Чем СообщитьПользователю отличается от устаревшего Сообщить?
Метод Сообщить выводит простой текст в окно сообщений без привязки к данным и полям. СообщитьПользователю (через объект СообщениеПользователю) позволяет указать поле формы, привязаться к объекту данных и управлять отображением. В новых разработках следует использовать только объектный вариант.
Почему сообщение, созданное на сервере, не видно в форме?
Чаще всего не вызван метод УстановитьДанные() либо сообщение создаётся вне контекста формы — например, в фоновом задании или регламентной операции. В фоновых заданиях сообщения пользователю не доставляются в принципе: используйте журнал регистрации или механизм длительных операций БСП.
Можно ли показать вопрос пользователю из серверной процедуры?
Нет. Интерактивные диалоги доступны только на клиенте. Если решение нужно посреди серверной операции, разбейте алгоритм: клиент спрашивает пользователя, затем вызывает серверный метод с выбранным параметром.
Как вывести пользователю текст перехваченной ошибки?
В блоке Исключение получите описание через ИнформацияОбОшибке() или ОписаниеОшибки(), запишите подробное представление в журнал регистрации, а пользователю выведите краткое понятное сообщение через СообщитьПользователю. Передавать сырой технический текст напрямую не стоит.
Что произойдёт с данными при ВызватьИсключение внутри транзакции?
Платформа откатит всю активную транзакцию: все изменения, сделанные с момента НачатьТранзакцию(), будут отменены. Это безопасно для целостности данных, но приведёт к потере промежуточных результатов, если они рассчитывали на фиксацию.
Когда оправдано ПоказатьОповещениеПользователя вместо сообщения об ошибке?
Оповещение подходит для информационных событий: завершение фоновой обработки, успешная синхронизация, напоминание. Для ошибок оно не подходит — всплывающее окно легко пропустить, а пользователь должен гарантированно увидеть проблему и понять, что делать.
Что важно запомнить
Ошибки заполнения показывайте через СообщитьПользователю с привязкой к полю и Отказ = Истина; критические сбои останавливайте через ВызватьИсключение; диалоги с вопросом — только на клиенте через описание оповещения. Текст сообщения должен объяснять, что случилось и что делать, а технические детали отправляйте в журнал регистрации.