При работе любого приложения могут возникнуть ситуации, приводящие к аварийному завершению работы программы. Еще хуже, если такие ошибки приводят к появлению уязвимостей и возможностям их эксплуатации. Для предотвращения проблем, связанных с исключительными ситуациями при работе приложений, применяются специальные обработчики исключений.
В этой статье мы поговорим об обработке исключений в конфигурациях 1С. В частности, мы посмотрим то как можно перехватывать исключения правильно и не очень правильно. Все перечисленные рекомендации представлены на сайте данного вендора и являются обязательными, если не указано иное. Статья может быть полезна архитекторам и разработчикам приложений в 1С.
А может не надо
В целом, 1С рекомендует не перехватывать исключения. Например, зачастую разработчики перехватывают исключения для того, чтобы отобразить сообщение об ошибке. Это позволяет понять на каком шаге работы алгоритма произошел сбой.
Однако платформа 1С автоматически выводит сообщение об ошибке для каждого не перехваченного исключения и вы и так получите сообщение о том, по какой причине сработало исключение.
Тем не менее, иногда вам может понадобиться перехватить исключение. Например, вы можете изменить сообщение об ошибке, сделав его полностью понятным для конечных пользователей. Но даже если вы это сделаете, вам все равно придется зарегистрировать ошибку в журнале событий, чтобы системный администратор мог определить проблему и предоставить подробную информацию об ошибке по запросу в службу технической поддержки.
Хорошей рекомендацией является обязательная запись сообщений об ошибках в журнал событий. В результате это сообщение не потеряется и у вас будет точное время, когда произошла данная ошибка. А для пользователей можно отображать краткое описание для пользователей.
Рассматриваем примеры
В первом примере бизнес‑логика сервера вызывается клиентом во время интерактивного взаимодействия с пользователем:
//на клиенте
Procedure PerformAction()
// Код, вызывающий ошибку
...
EndProcedure
В этом блоке с кодом нам необходимо добавить обработчик исключения. Логичным было бы использовать следующую конструкцию:
// на клиенте
Try
PerformAction();
Except
DoMessageBox("Cannot perform the action.");
EndTry;
Однако, ограничиваться выводом сообщения только на клиенте не стоит, так как этого явно недостаточно для последующей отладки. Более правильным будет следующий вариант:
//на сервере
Procedure PerformAction()
Try
// Код, вызывающий ошибку
...
Except
// Запись события в журнал
WriteLogEvent(NStr("en = 'Performing action'"),
EventLogLevel.Error, , ,
DetailErrorDescription(ErrorInfo()));
Raise;
EndTry;
EndProcedure
И на клиенте:
Try
PerformAction();
Except
MessageText = BriefErrorDescription(ErrorInfo());
DoMessageBox(NStr("en = 'Cannot perform the action. Reason:'" + Chars.LF + MessageText);
EndTry;
Теперь рассмотрим другой пример. У клиента реализована какая‑то логика при сохранении файла на диск:
//На клиенте
Procedure CreateFileOnDisk()
// Код, вызывающий ошибку
...
EndProcedure
Здесь рекомендуется сделать дополнительный вызов сервера для регистрации неудачного выполнения операции в журнале событий:
//на клиенте
Try
// Код, вызывающий ошибку
CreateFileOnDisk();
Except
MessageText = BriefErrorDescription(ErrorInfo());
DoMessageBox(NStr("en = 'Cannot perform the action. Reason:'") + Chars.LF + MessageText);
WriteFileOperationError(DetailErrorDescription(ErrorInfo()));
EndTry;
//на сервере
Procedure WriteFileOperationError(...)
WriteLogEvent(NStr("en = 'Performing action'"),
EventLogLevel.Error, , ,
DetailErrorDescription(ErrorInfo()));
EndProcedure
Вообще, хорошей практикой должно стать правило не перехватывать исключения без его фиксации в журнале событий:
Try
// Код, вызывающий ошибку
...
Except
// Перехват исключения
EndTry;
Как правило, такие конструкции создают проблемы, которые невозможно обнаружить. Правильным был бы следующий вариант написания кода:
Try
// Код, вызывающий ошибку
...
Except
// Комментарий, объясняющий, почему исключение было поймано без уведомления конечных пользователей.
// ...
// Запись в журнал событий.
WriteLogEvent(NStr("en = 'Performing action'"),
EventLogLevel.Error, , ,
DetailErrorDescription(ErrorInfo()));
EndTry;
Еще одна рекомендация по работе с исключениями: не используйте исключения для проверки доступности атрибутов объектов, методов, шаблонов и так далее. Это может привести к ошибкам, которые трудно обнаружить, а также усложнит отладку в режиме «Остановка при ошибках», используемом в 1С:EDT.
Вместо перехвата исключений в рекомендуется использовать операции с метаданными для явной проверки доступности атрибута, шаблона или другой части данных. Если доступность некоторых данных зависит от опций развертывания библиотеки, отразить этот факт в переопределяемых модулях.
Также пересмотрите логику методов, которые ловят исключения. Например, вы можете реализовать параметры, определяющие доступность метода или свойства объекта.
Давайте рассмотрим неправильный вариант реализации:
Try
ContextERPServer.GetTemplate("ExchangeComponent");
Path = ContextERPServer.PathToObject + ".Template.ExchangeComponent");
Except
EndTry;
Более правильным вариантом реализации будет следующий:
ExchangeComponentTemplate = ContextERPServer.Metadata().Templates.Find("ExchangeComponent");
If ExchangeComponentTemplate <> Undefined Then
PathToTemplate = ExchangeComponent.FullName();
EndIf;
Здесь мы вообще не используем исключения, а вместо этого просто проверяем условия.
Далее поговорим о транзакциях. Внутри транзакций рекомендуется использовать следующий формат обработки исключений:
BeginTransaction();
Try
Query = New Query("...");
Selection = Query.Execute().Select();
While Selection.Next() Do
...
EndDo;
CommitTransaction();
Except
RollbackTransaction();
WriteLogEvent(NStr("en = 'Performing action'"),
EventLogLevel.Error, , ,
DetailErrorDescription(ErrorInfo()));
Raise;
EndTry;
Поскольку исключение не приводит к немедленному откату транзакции, а запрещает ее фиксацию, каждый из вызовов BeginTransaction
должен иметь соответствующий вызов CommitTransaction
или RollbackTransaction
.
Заключение
В этой статье мы рассмотрели несколько рекомендаций по работе с исключениями в 1С. Основным является то, что если вы используете исключение, то обязательно фиксируйте его срабатывание в журнале событий. И в некоторых случаях иногда бывает лучше вообще не использовать исключения.
Если вы работаете с 1С и стремитесь системно подходить к проектированию и сопровождению решений, приглашаем вас на серию открытых уроков курса «Архитектор 1С». Это возможность ознакомиться с подходами, инструментами и практиками, которые применяются в современной архитектуре систем на базе 1С.
30 июля в 19:00 — «Как документировать сервисы 1С по OpenAPI (Swagger)?». На этом уроке разберём, как описывать интерфейсы ваших сервисов в удобном и читаемом формате.
13 августа в 19:00 — «Yaxunit как инструмент автоматизированной валидации API по схеме OpenAPI». Участники узнают, как использовать Yaxunit для проверки соответствия сервисов заявленным спецификациям.
19 августа в 19:00 — разбор темы «Проектирование архитектуры систем предприятия в интеграциях с 1С», где будет представлен подход к построению архитектуры с учётом взаимодействия 1С с внешними системами.
Также доступно вступительное тестирование, позволяющее проверить понимание тем и оценить уровень ваших навыков.
Комментарии (10)
ahhilless
30.07.2025 13:21"При работе любого приложения могут возникнуть ситуации, приводящие к аварийному завершению работы программы." 1с :(
AndreyBAV
30.07.2025 13:21писать на английском дурной тон, если конечно проект не международный
stanukih
30.07.2025 13:21Много ли международных проектов на 1с, где не только пользователи, но и разработчики предпочитают английский?
RomanDrDev
30.07.2025 13:21Есть проекты, где использование английского языка является требованием бизнеса. Но таких, конечно, очень мало.
Fragster
Я думал будет про https://wonderland.v8.1c.ru/blog/razvitie-mekhanizma-otobrazheniya-oshibok/?sphrase_id=3823953, а тут какая-то абстракция, не привязанная к 1с (код на 1с на английском смотрится реально странно). Да и вообще про отличия обработки исключений в 1с от
нормальныхболее распространенных среди посетителей хабра языков было бы неплохо рассказать. Про особенности в 1с-исполнителе, если они есть, тоже было бы интересно. Про технологических журнал (а может быть и средства для его анализа и выгрузку в графану)XLeshiy
1C поддерживает синтаксис на английском и примеры как раз из 1с.
Это выпендрёж чистой воды и считается дурным тоном.
Программисты 1С пишут на русском.
Fragster
Да я чуть-чуть в курсе. Мой комментарий про то, что в статье общие рекомендации, подходящие, грубо говоря, для всех языков программирования.
А про особенности 1с типа отсустсвие finally или про распространенное "В данной транзакции уже происходили ошибки" с причинами появления (причины в общем случае и частные проявления, в т.ч. труднопонимаемые для новичков типа Сообщить(ДанныеСсылочногоТипа)) и что с этим делать.
Про обработку в асинхронных и "доасинхронных" (с Описанием оповещения) тоже ни слова.
XLeshiy
Зато реклама курсов есть)
yurikmellon
Все же понимают, что весь англоязычный мир видит код на C, Python и др. точно так же, как тот, для кого родной русский, видит код 1С?
Fragster
В современном С можно использовать идентификаторы на русском, и, путем несложных манипуляций, заменить все ключевые слова на русские аналоги. Но никто так не делает. А вот в экосистеме 1с 99% кода на русском языке, поэтому использование английского варианта является маргинальным.