14-bo‘lim
Xatoliklarni boshqarish
Try, Catch va Finally, xato turlari, Throw bilan xato ko'tarish, o'z xato sinfingiz, Using va nega On Error eskirgan.
Ushbu bo‘lim mundarijasi
Dastur ishlayotganda kutilmagan holatlar yuz beradi: fayl topilmaydi, foydalanuvchi harf yozadi, tarmoq uzilaadi. Bularni istisno (exception) deb ataymiz.
Try va Catch #
Module Dastur
Sub Main()
Try
Dim matn As String = "salom"
Dim son As Integer = CInt(matn)
Console.WriteLine(son)
Catch ex As InvalidCastException
Console.WriteLine("Bu matnni songa aylantirib bo'lmadi")
End Try
Console.WriteLine("Dastur davom etmoqda")
End Sub
End Module
Bu matnni songa aylantirib bo'lmadi
Dastur davom etmoqda
Try blokidagi kod xato bersa, dastur to'xtamaydi - boshqaruv
Catch ga o'tadi.
Bir necha Catch #
Module Dastur
Sub Sinov(bolovchi As Integer, sonlar() As Integer, indeks As Integer)
Try
Console.WriteLine(sonlar(indeks) \ bolovchi)
Catch ex As DivideByZeroException
Console.WriteLine("Nolga bo'lib bo'lmaydi")
Catch ex As IndexOutOfRangeException
Console.WriteLine("Bunday indeks yo'q")
Catch ex As Exception
Console.WriteLine($"Boshqa xato: {ex.GetType().Name}")
End Try
End Sub
Sub Main()
Dim sonlar() As Integer = {10, 20, 30}
Sinov(2, sonlar, 0)
Sinov(0, sonlar, 1)
Sinov(2, sonlar, 99)
End Sub
End Module
5
Nolga bo'lib bo'lmaydi
Bunday indeks yo'q
Catch bloklari yuqoridan pastga tekshiriladi va birinchi mos
kelgani ishlaydi.
Exception - hamma xatolarning otasi. Shuning uchun uni eng
oxirida yozish kerak. Yuqoriga qo'ysangiz, qolganlari hech qachon
ishlamaydi va kompilyator ogohlantirish beradi.
Xato haqida ma'lumot #
Module Dastur
Sub Main()
Try
Dim sonlar() As Integer = {1, 2, 3}
Console.WriteLine(sonlar(10))
Catch ex As Exception
Console.WriteLine($"Turi: {ex.GetType().Name}")
Dim bormi As Boolean = Not String.IsNullOrEmpty(ex.Message)
Console.WriteLine($"Xabar bormi: {bormi}")
End Try
End Sub
End Module
Turi: IndexOutOfRangeException
Xabar bormi: True
ex.Message matni .NET versiyasiga va tizim tiliga qarab
o'zgarishi mumkin. Shuning uchun bu darslikda uning borligi
tekshirildi, matnning o'zi emas.
Haqiqiy dasturda esa ex.Message ni jurnalga yozish juda foydali -
muammoni topishning eng tez yo'li shu.
Finally #
Module Dastur
Function Bol(a As Integer, b As Integer) As String
Try
Return (a \ b).ToString()
Catch ex As DivideByZeroException
Return "xato"
Finally
Console.WriteLine(" Finally bajarildi")
End Try
End Function
Sub Main()
Console.WriteLine(Bol(10, 2))
Console.WriteLine(Bol(10, 0))
End Sub
End Module
Finally bajarildi
5
Finally bajarildi
xato
Finally har doim bajariladi: xato bo'lsa ham, bo'lmasa ham,
hatto Return dan keyin ham. Fayl yoki ulanishni yopish uchun
ishlatiladi.
Xatoni o'zingiz ko'tarish #
Module Dastur
Sub YoshTekshir(yosh As Integer)
If yosh < 0 Then
Throw New ArgumentException("Yosh manfiy bo'lishi mumkin emas")
End If
If yosh > 150 Then
Throw New ArgumentOutOfRangeException("yosh")
End If
Console.WriteLine($"Yosh qabul qilindi: {yosh}")
End Sub
Sub Main()
YoshTekshir(25)
Try
YoshTekshir(-5)
Catch ex As ArgumentException
Console.WriteLine($"Ushlandi: {ex.GetType().Name}")
End Try
End Sub
End Module
Yosh qabul qilindi: 25
Ushlandi: ArgumentException
Throw - "bu holatni men bajara olmayman, chaqiruvchi hal qilsin"
degan xabar.
O'z xato sinfingiz #
Public Class QoldiqYetarliEmasException
Inherits Exception
Public Property Yetishmayotgan As Decimal
Public Sub New(yetishmayotgan As Decimal)
MyBase.New($"Hisobda {yetishmayotgan} so'm yetishmayapti")
Me.Yetishmayotgan = yetishmayotgan
End Sub
End Class
Public Class Hisob
Private _qoldiq As Decimal
Public Sub New(boshlangich As Decimal)
_qoldiq = boshlangich
End Sub
Public Sub Yechish(summa As Decimal)
If summa > _qoldiq Then
Throw New QoldiqYetarliEmasException(summa - _qoldiq)
End If
_qoldiq -= summa
Console.WriteLine($"Yechildi. Qoldiq: {_qoldiq}")
End Sub
End Class
Module Dastur
Sub Main()
Dim h As New Hisob(500000D)
Try
h.Yechish(200000D)
h.Yechish(900000D)
Catch ex As QoldiqYetarliEmasException
Console.WriteLine(ex.Message)
Console.WriteLine($"Yetishmayotgan summa: {ex.Yetishmayotgan}")
End Try
End Sub
End Module
Yechildi. Qoldiq: 300000
Hisobda 600000 so'm yetishmayapti
Yetishmayotgan summa: 600000
ex.Message - konstruktorda MyBase.New ga berilgan matn. Asosiy
foydasi esa Yetishmayotgan xossasi: oddiy Exception faqat matn
tashiydi, o'z sinfingiz esa ishlov berish uchun yaroqli ma'lumot
ham tashiy oladi.
Matnni tahlil qilib son ajratib olishga urinish - noto'g'ri yo'l. Kerakli qiymatni xossa sifatida qo'shing.
Using - resursni o'zi yopadi #
Imports System.IO
Module Dastur
Sub Main()
Dim yol As String = "sinov.txt"
Using yozuvchi As New StreamWriter(yol)
yozuvchi.WriteLine("Birinchi qator")
yozuvchi.WriteLine("Ikkinchi qator")
End Using
Console.WriteLine(File.ReadAllText(yol).Trim())
File.Delete(yol)
End Sub
End Module
Birinchi qator
Ikkinchi qator
Using bloki tugaganda - xato bo'lsa ham - resurs avtomatik
yopiladi. Bu Try/Finally ning qisqa shakli.
Using yozmasangiz va xato yuz bersa, fayl ochiq qolishi mumkin.
Keyin uni boshqa dastur o'chira ham, o'zgartira ham olmaydi.
Qoida oddiy: StreamReader, StreamWriter, ma'lumotlar bazasi
ulanishi - bularning hammasi Using ichida bo'lishi kerak.
Xatoni qayta ko'tarish #
Module Dastur
Sub Ichki()
Throw New InvalidOperationException("ichki xato")
End Sub
Sub Ortadagi()
Try
Ichki()
Catch ex As Exception
Console.WriteLine("Jurnalga yozildi")
Throw
End Try
End Sub
Sub Main()
Try
Ortadagi()
Catch ex As Exception
Console.WriteLine($"Yuqorida ushlandi: {ex.Message}")
End Try
End Sub
End Module
Jurnalga yozildi
Yuqorida ushlandi: ichki xato
Yolg'iz Throw - "xatoni o'zgartirmasdan yuqoriga uzat" degani.
Throw ex deb yozsangiz, xatoning kelib chiqish joyi yo'qoladi.
On Error - eskirgan usul #
' VB6 uslubi - yangi kodda ishlatmang
On Error Resume Next
Dim son As Integer = CInt("salom")
On Error Goto 0
Bu ko'rsatma "xato bo'lsa, e'tiborsiz qoldir va davom et" degani.
Natijada dastur noto'g'ri ma'lumot bilan ishlashda davom etadi va haqiqiy muammo ancha keyin, butunlay boshqa joyda ko'rinadi. Sababini topish esa deyarli imkonsiz bo'lib qoladi.
VB.NET da u hali ham ishlaydi (eski kod uchun), lekin yangi kodda
hech qachon ishlatmang. Try/Catch bor.
Qachon ushlash kerak #
| Holat | To'g'ri yo'l |
|---|---|
| Foydalanuvchi noto'g'ri son yozdi | TryParse - istisno umuman kerak emas |
| Fayl yo'qligi mumkin | File.Exists tekshiruvi yoki Catch |
| Tarmoq uzilishi | Catch - oldindan bilib bo'lmaydi |
| Dasturchining xatosi | Ushlamang - kod tuzatilishi kerak |
Bu eng yomon namuna:
Try
' biror ish
Catch ex As Exception
' hech narsa
End Try
Xato yuz berdi, lekin hech kim bilmaydi. Dastur "ishlayotgandek" ko'rinadi, aslida esa ish bajarilmadi.
Hech bo'lmaganda xabarni jurnalga yozing yoki ekranga chiqaring.
- Nolga bo'lishni
Try/Catchbilan ushlang. - Massivdan chiqib ketishni alohida
Catchbilan ushlang. Exceptionni birinchiCatchga qo'yib, ogohlantirishni o'qing.Finallyblokining har doim bajarilishini isbotlang.- Manfiy yoshda
ArgumentExceptionko'taring. MaxsulotTopilmadiExceptionnomli o'z xato sinfingizni yozing.- Unga qo'shimcha xossa qo'shib,
Catchda o'qing. Usingbilan faylga yozing va uni o'chiring.- Xatoni ushlab, jurnalga yozib,
Throwbilan qayta ko'taring. TryParsevaTry/Catchdan qaysi biri qachon to'g'ri kelishini yozing.
Xulosa #
Try/Catchxato yuz berganda dasturning to'xtashiga yo'l qo'ymaydi.Catchbloklari aniqrog'idan umumiyga qarab yoziladi;Exceptioneng oxirida.Finallyhar doim bajariladi - resursni yopish uchun.Throw New ...bilan o'z xatongizni ko'tarasiz.- O'z xato sinfingiz
Exceptiondan meros oladi va qo'shimcha ma'lumot tashiy oladi. Using- fayl va ulanishlar uchun majburiy odat.- Yolg'iz
Throwxatoning kelib chiqishini saqlaydi,Throw exesa yo'qotadi. On Error Resume Next- eski va xavfli; ishlatmang.- Kutilgan holat uchun
TryParse, kutilmagan uchunTry/Catch.
Keyingi bo'limda fayllar va JSON bilan ishlaymiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.