Sıfıra bölmə, tapılmayan fayl, qəfil kəsilən şəbəkə bağlantısı: real proqramda xətalar qaçılmazdır. Problem xətanın baş verməsində deyil, ona hazır olmamaqdadır. 1C:Enterprise dilində istisnaların (exceptions) idarə edilməsi Попытка ... Исключение ... КонецПопытки konstruksiyası ilə aparılır. Bu məqalədə onun işləmə məntiqini, tipik səhvləri, ВызватьИсключение, ИнформацияОбОшибке() və tranzaksiyalarla düzgün birgə istifadəni araşdırırıq.
Konstruksiyanın icra ardıcıllığını, xətanı “udmağın” niyə təhlükəli olduğunu, xətanı necə qəsdən yaratmaq və yuxarı ötürmək lazım olduğunu, xəta haqqında tam məlumatı necə əldə etməyi, tranzaksiya və Hadisələr jurnalı ilə düzgün sxemi.
| № | Mövzu | Qısa nəticə |
|---|---|---|
| 1 | Попытка ... Исключение | Xəta baş verən sətirdən sonrakı kod atılır, idarəetmə Исключение blokuna keçir |
| 2 | Xətanı “udmaq” | Boş Исключение bloku gizli və izlənməz xətalara yol açır |
| 3 | ВызватьИсключение | Xətanı qəsdən yaradır; blok daxilində parametrsiz yazılsa, xətanı yuxarı ötürür |
| 4 | ИнформацияОбОшибке() | Xətanın təsviri, modulu, sətri və səbəb zənciri |
| 5 | Tranzaksiya | Xətada dəyişiklikləri özünüz geri qaytarmalısınız (ОтменитьТранзакцию) |
| 6 | Nə vaxt istifadə etməli | Gözlənilən hallar yoxlamayla, gözlənilməzlər Попытка ilə idarə olunur |
1. Konstruksiya necə işləyir?
Xəta riski olan kod Попытка blokuna yazılır. İcra ardıcıllığı belədir:
- Təhlükəli kod
Попыткаblokunda icra olunur. - Hər hansı sətirdə xəta baş verərsə, blokun qalan sətirləri icra olunmur.
- İdarəetmə dərhal
Исключениеblokuna keçir. - Xəta olmasa,
Исключениеbloku ümumiyyətlə işləmir.
Sifir = 0;
Попытка
Netice = 10 / Sifir; // burada xəta baş verir
Сообщить("Nəticə: " + Netice); // bu sətir icra OLUNMUR
Исключение
Сообщить("Xəta baş verdi: " + ОписаниеОшибки());
КонецПопытки;
Eyni kodun icra izi
1. Попытка yalnız icra zamanı (runtime) yaranan xətaları tutur. Sintaksis xətaları kod icra olunmamış kompilyasiya və ya konfiqurasiya yoxlaması mərhələsində aşkarlanır.
2. BSL dilində Finally (həmişə icra olunan blok) yoxdur. Resursu (fayl, bağlantı) bağlamaq lazımdırsa, bunu КонецПопытки-dən sonra ayrıca yazmaq lazımdır (2-ci hissədəki nümunəyə baxın).
3. Попытка xətanı tutur, amma verilənlər bazasında artıq edilmiş dəyişiklikləri geri qaytarmır. Bu barədə 5-ci bölmədə danışırıq.
Bənzətmə: təhlükəsizlik kəməri
Попытка təhlükəsizlik kəmərinə bənzəyir: qəza olsa da, sürücünü qoruyur. Lakin kəmər maşının zədələnməsini aradan qaldırmır. Eynilə, Попытка proqramın çökməsinin qarşısını alır, amma xətadan sonra məlumatın düzgün vəziyyətdə qalması üçün özünüz tədbir görməlisiniz.
2. Xətanı “udmaq” ən böyük günahdır
Yeni başlayanların ən tipik səhvi Исключение blokunu boş buraxmaqdır. Proqram çökmür, amma xəta da heç yerdə görünmür.
// PİS: xəta gizlədilir
Попытка
SenediYaz(Sened);
Исключение
КонецПопытки;
Bu yanaşma gələcəkdə səbəbini tapmaq çətin olan “kabus” xətalara gətirir: məlumat natamam yazılır, hesablamalar sürüşür, istifadəçi isə əməliyyatın uğursuz olduğunu bilmir. Xəta ilə bağlı üç mümkün strategiya var:
| Strategiya | Xəta görünür? | Jurnalda qalır? | İstifadəçi məlumatlanır? | Qiymətləndirmə |
|---|---|---|---|---|
Boş Исключение (udmaq) | Xeyr | Xeyr | Xeyr | Yolverilməzdir |
| Tutmaq və istifadəçiyə mesaj vermək | Bəli | İstəyə görə | Bəli | Doğrudur (xətanı həll etmək mümkündürsə) |
| Jurnala yazmaq və yuxarı ötürmək | Bəli | Bəli | Yuxarı səviyyə qərar verir | Doğrudur (xətanı bu səviyyədə həll etmək olmursa) |
Xəta ya burada tam idarə olunmalı və istifadəçiyə başa düşülən mesaj verilməlidir, ya da yuxarıya ötürülməlidir. Üçüncü variant (səssizcə udmaq) yoxdur.
Resursun bağlanması nümunəsi (Finally olmadığı üçün)
Oxuyucu = Неопределено;
Metn = "";
Попытка
Oxuyucu = Новый ЧтениеТекста(FaylinYolu, КодировкаТекста.UTF8);
Metn = Oxuyucu.Прочитать();
Исключение
Сообщить("Fayl oxuna bilmədi: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
// Bu hissə həm uğurlu, həm xətalı halda icra olunur
Если Oxuyucu <> Неопределено Тогда
Oxuyucu.Закрыть();
КонецЕсли;
3. ВызватьИсключение: xətanı qəsdən yaratmaq və ötürmək
Funksiyaya yanlış və ya təhlükəli məlumat daxil olubsa, kod səssizcə işləməməlidir. ВызватьИсключение komandası məqsədli şəkildə istisna yaradır. Nəticə xətanı çağıran koda ötürülür.
Функция Bol(A, B)
Если B = 0 Тогда
ВызватьИсключение "Sıfıra bölmək olmaz!";
КонецЕсли;
Возврат A / B;
КонецФункции
Попытка
Netice = Bol(10, 0);
Исключение
Сообщить(КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Xətanı yuxarı ötürmək (re-throw)
Исключение bloku daxilində ВызватьИсключение; parametrsiz yazılsa, tutulmuş xəta olduğu kimi yuxarıya ötürülür. Bu halda əvvəlcə lazımi əməliyyat (məsələn, jurnala yazmaq) aparılır, qərarı isə çağıran səviyyə verir.
Попытка
ServerdeEmal(Parametr);
Исключение
// 1. Hadisələr jurnalına yazırıq
ЗаписьЖурналаРегистрации("Emal.Xeta", УровеньЖурналаРегистрации.Ошибка,,,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
// 2. Xətanı yuxarı ötürürük
ВызватьИсключение;
КонецПопытки;
Parametrsiz ВызватьИсключение; yalnız Исключение bloku daxilində yazıla bilər. Həmin blokdan kənarda belə yazılış düzgün deyil. Əgər ВызватьИсключение bir Попытка blokunun içindədirsə, xəta həmin blokun özü tərəfindən tutulur.
4. Xətanın “pasportu”: ИнформацияОбОшибке()
ИнформацияОбОшибке() cari xəta haqqında bütün texniki məlumatı özündə saxlayan xüsusi obyekt qaytarır (Структура deyil). Əsas xassələri:
| Xassə | Nəyi göstərir |
|---|---|
Описание | Xətanın mətni |
ИмяМодуля | Xətanın baş verdiyi modulun adı |
НомерСтроки | Moduldakı sətir nömrəsi |
ИсходнаяСтрока | Xətalı sətrin mətni (bəzi hallarda boş ola bilər) |
Причина | Bu xətanı yaradan daha dərin xəta (başqa ИнформацияОбОшибке obyekti) və ya Неопределено |
Попытка
Netice = 10 / 0;
Исключение
Info = ИнформацияОбОшибке();
Сообщить("Xətanın mətni: " + Info.Описание);
Сообщить("Modul: " + Info.ИмяМодуля);
Сообщить("Sətir: " + Info.НомерСтроки);
КонецПопытки;
Səbəb zənciri: əsl ilkin səbəbi necə tapmalı?
Xəta bir neçə çağırış səviyyəsindən keçəndə Причина xassəsi zəncir yaradır. Info.Причина yalnız növbəti səviyyəni göstərir, ilkin səbəb isə zəncirin sonundadır. Ona çatmaq üçün dövr lazımdır:
Info = ИнформацияОбОшибке();
Koken = Info;
Пока Koken.Причина <> Неопределено Цикл
Koken = Koken.Причина;
КонецЦикла;
Сообщить("İlkin səbəb: " + Koken.Описание);
Üç “təqdimat” funksiyası
| Funksiya | Nə üçün |
|---|---|
ОписаниеОшибки() | Cari xətanın təsviri (Исключение bloku daxilində) |
КраткоеПредставлениеОшибки(Info) | İstifadəçiyə göstərmək üçün qısa, texniki detalsız mətn |
ПодробноеПредставлениеОшибки(Info) | Jurnal üçün tam məlumat: modul, sətir, səbəb zənciri |
Funksiyaların qaytardığı mətnin dəqiq görünüşü platformanın versiyasından və xətanın tipindən asılı ola bilər. Mətnin formatını öz mühitinizdə yoxlayın.
İstifadəçi nəyi görməlidir?
İstifadəçiyə texniki sistem xətasını deyil, aydın və istiqamətləndirici mesajı göstərin. Texniki detalları isə Hadisələr jurnalına yazın.
5. Попытка və tranzaksiya: dəyişiklikləri geri qaytarmaq
Bir neçə obyekt ardıcıl yazılırsa (sənəd, hərəkətlər, qeydlər), ortada xəta baş verəndə bəziləri yazılmış, bəziləri yazılmamış qala bilər. Bunun qarşısını almaq üçün əməliyyatları tranzaksiyaya salın. Попытка özü bazadakı dəyişiklikləri geri qaytarmır, bunu ОтменитьТранзакцию() ilə siz etməlisiniz.
НачатьТранзакцию();
Попытка
// bir neçə əlaqəli yazı əməliyyatı (obyekt adı nümunə üçündür)
Sened = Документы.Realizasiya.СоздатьДокумент();
Sened.Дата = ТекущаяДата();
Sened.Записать(РежимЗаписиДокумента.Проведение);
ZiyadeYazi(Sened.Ссылка);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ЗаписьЖурналаРегистрации("Realizasiya.Yazma", УровеньЖурналаРегистрации.Ошибка,,,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение;
КонецПопытки;
Tranzaksiya blokunda xətanı tutub davam etmək (tranzaksiyanı ləğv etmədən) təhlükəlidir. Tranzaksiya içində xəta olduqda, onu həmişə ləğv edin, sonra isə nə edəcəyinizə qərar verin.
6. Попытка nə vaxt lazımdır?
Попытка hər sətri bükmək üçün deyil, yoxlamaqla qarşısı alınmayan gözlənilməz hallar üçündür. Gözlənilən vəziyyəti isə sadə şərtlə yoxlamaq daha aydın və daha sürətlidir.
| Vəziyyət | Yaxşı yanaşma |
|---|---|
| Bölən sıfırdır | Если B = 0 Тогда ... yoxlaması |
| Dəyər doldurulmayıb | ЗначениеЗаполнено() və ya Неопределено yoxlaması |
| Mətn ədədə çevrilməlidir | ОписаниеТипов("Число").ПривестиЗначение() |
| Fayl, şəbəkə, xarici sistem, COM, veb-xidmət | Попытка + jurnal + mesaj |
| Bir neçə əlaqəli yazı əməliyyatı | Попытка + tranzaksiya |
Etibarlılıq pilləkəni (konseptual)
Aşağıdakı diaqram konseptualdır, real ölçmə deyil: xətaya yanaşmanın keyfiyyət səviyyələrini göstərir.
7. Hadisələr jurnalı: xətanın izi
ЗаписьЖурналаРегистрации() funksiyası hadisəni 1C Hadisələr jurnalına (Журнал регистрации) yazır. Bu, istifadəçi mesajından fərqli olaraq, sonradan analiz üçün qalan izdir.
| Parametr | Mənası |
|---|---|
ИмяСобытия | Hadisənin adı (məsələn, "Realizasiya.Yazma"), jurnalda filtr üçün istifadə olunur |
Уровень | Информация, Предупреждение, Ошибка, Примечание |
ОбъектМетаданных, Данные | İstəyə görə: əlaqəli konfiqurasiya obyekti və məlumat |
Комментарий | Mətn, xətalar üçün ПодробноеПредставлениеОшибки() nəticəsi |
Yekun: 6 qayda yadda saxlayın
- Попытка yalnız icra zamanı xətalarını tutur və xətadan sonrakı kodu atır.
- Boş Исключение yazmayın. Xətanı ya idarə edin, ya da yuxarı ötürün.
- ВызватьИсключение ilə yanlış vəziyyəti dərhal bildirin; blokda parametrsiz yazılışı xətanı yuxarı ötürür.
- ИнформацияОбОшибке() ilə sətir, modul və səbəb zəncirini toplayın; ilkin səbəb üçün dövrdən istifadə edin.
- Tranzaksiyada xətada həmişə
ОтменитьТранзакцию()çağırın. - Gözlənilən halı şərtlə, gözlənilməz halı Попытка ilə idarə edin; istifadəçiyə dost mesaj, jurnala texniki detal verin.
Tez-tez verilən suallar
Попытка proqramın sürətinə təsir edirmi?
Xəta baş vermədikdə təsiri adətən nəzərə çarpmır. Yenə də onu dövr daxilində lazımsız yerə və hər sətirdə işlətməyin, çünki kodun oxunaqlılığını azaldır.
Попытка bazadakı dəyişiklikləri geri qaytarırmı?
Xeyr. Dəyişiklikləri geri qaytarmaq üçün tranzaksiya istifadə edin və xətada ОтменитьТранзакцию() çağırın.
ОписаниеОшибки() yoxsa ИнформацияОбОшибке()?
Sadə mətn üçün ОписаниеОшибки() kifayətdir. Modul, sətir və səbəb zənciri lazımdırsa, ИнформацияОбОшибке() istifadə edin.
Finally kimi blok varmı?
BSL dilində ayrıca Finally bloku yoxdur. Resursları bağlamaq üçün КонецПопытки-dən sonra yoxlamalı kod yazın.
1C proqramınızın xətalara qarşı dayanıqlığını artırmaq istəyirsiniz?
KodYaz komandası 1C proqramlaşdırması, kodun auditi, inteqrasiya və fərdi həllər üzrə sizə kömək edə bilər. Bizimlə əlaqə saxlayın.






