Меню


Курсы СтимулСправочникПолезные материалы1С:Предприятие 8.2РазработчикамСоглашения при написании ко…

1С:Предприятие 8.2 /
Разработчикам /
Соглашения при написании кода

Оглавление

Перехват исключений в коде

Частные случаи некорректного использования и перехвата исключений

 

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

В общем случае не рекомендуется перехватывать исключения. В частности не нужно перехватывать исключения только ради выдачи сообщения об ошибке. Необработанное исключение в любом случае будет выдано пользователю в виде сообщения об ошибке.

Тем не менее необходимость перехвата исключений в коде все же возникает. Например, для того чтобы уточнить текст ошибки, дополнив его прикладной, понятной конечному пользователю , информацией. Однако при этом необходимо фиксировать причину ошибки в журнале регистрации для того, чтобы системный администратор имел возможность выполнить диагностику проблемы и при необходимости передать информацию об ошибке в службу технической поддержки.

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

Частные случаи некорректного использования и перехвата исключений

Область применения (уточнение): управляемое приложение, обычное приложение.

1. Если имеется некоторая серверная бизнес-логика, которая вызывается с клиента при интерактивной работе пользователя:

&НаСервере Процедура ВыполнитьОперацию() // код, приводящий к вызову исключения .... КонецПроцедуры

то неправильно:

// на клиенте Попытка ВыполнитьОперацию(); Исключение Предупреждение("Операция не может быть выполнена."); КонецПопытки;

Правильно:

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

и тогда на клиенте:

Попытка ВыполнитьОперацию(); Исключение ТекстСообщения = КраткоеПредставлениеОшибки(ИнформацияОбОшибке()); Предупреждение(НСтр("ru = 'Операция не может быть выполнена по причине:'") + Символы.ПС + ТекстСообщения); КонецПопытки;

2. Если имеется некоторая клиентская бизнес-логика:

&НаКлиенте Процедура СоздатьФайлНаДиске() // код, приводящий к вызову исключения .... КонецПроцедуры

то рекомендуется делать дополнительный серверный вызов для протоколирования неудачного результата операции в журнал регистрации:

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

3. Недопустимо перехватывать любые исключения, бесследно для системного администратора:

Попытка // код, приводящий к вызову исключения .... Исключение // перехват любых исключений КонецПопытки;

Как правило , подобная конструкция скрывает реальную проблему, которую впоследствие невозможно диагностировать.
Правильно:

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

См. также Доступ к файловой системе из кода конфигурации , удаление временных файлов

4. Недопустимо делать проверки наличия у объекта реквизитов, методов, макетов и т.п., используя для этого исключения, т.к. это может привести к сложно диагностируемым ошибкам, а также затрудняет отладку в режиме «Останавливаться по ошибке».
Вместо перехвата исключений в этом случае рекомендуется:

Например, неправильно:

Попытка КонтекстЭДОСервер.ПолучитьМакет("КомпонентаОбмена"); ПутьВК = КонтекстЭДОСервер.ПутьКОбъекту + ".Макет.КомпонентаОбмена"; Исключение КонецПопытки;

Правильно:

МакетКомпонентыОбмена = КонтекстЭДОСервер.Метаданные().Макеты.Найти("КомпонентаОбмена"); Если МакетКомпонентыОбмена <> Неопределено Тогда ПутьКМакету = КомпонентаОбмена.ПолноеИмя() КонецЕсли;

5. При использовании транзакций следует придерживаться следующей схемы обработки исключений в коде на сервере:

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

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

6. Неправильно использовать исключения для приведения значения к типу. Для таких операций необходимо использовать возможности объекта ОписаниеТипов.

Например, неправильно:

Попытка КоличествоДнейРазрешения = Число(Значение); Исключение КоличествоДнейРазрешения = 0; // значение по умолчанию КонецПопытки;

Правильно:

ОписаниеТипа = Новый ОписаниеТипов("Число"); КоличествоДнейРазрешения = ОписаниеТипа.ПривестиЗначение(Значение);

Подписка на новости RSS

Мы на Facebook