Довідковий матеріал

Перехоплення винятків у коді

У загальному випадку не рекомендується перехоплювати виняток лише заради виведення повідомлення про помилку. Необроблений виняток у будь-якому разі буде показано користувачеві у вигляді повідомлення про помилку.

У загальному випадку не рекомендується перехоплювати виняток лише заради виведення повідомлення про помилку. Необроблений виняток у будь-якому разі буде показано користувачеві у вигляді повідомлення про помилку.

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

Рекомендується записувати до журналу реєстрації докладне подання винятку, а коротке подання додавати до тексту повідомлення користувачеві.

Приклад №1. Якщо є деяка серверна бізнес-логіка, яка викликається з клієнта під час інтерактивної роботи користувача:

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

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

 

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

Правильно:

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

і тоді на клієнті:

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

Приклад №2. Якщо є деяка клієнтська бізнес-логіка:

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

то рекомендується виконувати додатковий серверний виклик для протоколювання невдалого результату операції в журналі реєстрації:

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

Приклад № 3. Неприпустимо перехоплювати будь-які винятки безслідно для системного адміністратора:

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

Як правило, подібна конструкція приховує реальну проблему, яку згодом неможливо діагностувати.
Правильно:

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

Приклад № 4. Під час використання транзакцій слід дотримуватися такої схеми обробки винятків у коді на сервері:

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

Оскільки виняток не скасовує транзакцію одразу, але забороняє успішне завершення транзакції, то всі виклики НачатьТранзакцию, з одного боку, і ЗафиксироватьТранзакцию або ОтменитьТранзакцию, з іншого боку, мають бути парними.

Записатися телефоном