Darsliklar Ruby Exception Handling

Ruby Ruby Exception Handling

Xatolarni boshqarish (Exception Handling) — havaskor dasturchini professionaldan ajratib turadigan mavzu. Dastur ijrosi davomida kutilmagan holatlar — noto’g’ri ma’lumot, mavjud bo’lmagan fayl, nolga bo’lish — muqarrar yuzaga keladi. Ruby’da bunday holatlar begin, rescue va ensure orqali boshqariladi.

Exceptiondastur ijrosi vaqtida yuzaga keladigan g’ayrioddiy holatni ifodalovchi obyekt. Barcha standart xatolar StandardError sinfidan meros oladi. begin...rescue bloki xatoni ushlab, dasturning to’xtab qolishining oldini oladi.

begin va rescue

Xavfli kod begin blokiga, xato yuz berganda bajariladigan kod esa rescuega yoziladi:

begin
  natija = 10 / 0
  puts natija
rescue ZeroDivisionError => xato
  puts "Xato ushlandi: #{xato.message}"
end

puts "Dastur davom etmoqda"
Xato ushlandi: divided by 0
Dastur davom etmoqda

10 / 0ZeroDivisionError chiqaradi, rescue uni ushlab, tushunarli xabar berdi. Eng muhimi: dastur qulamadi, oxirgi qatorgacha ishlashda davom etdi. xato.message — xato haqidagi matnli tavsifni qaytaradi.

Bir necha rescue bloki

Turli xato turlarini alohida ushlash uchun bir necha rescue yozish mumkin — ular yuqoridan pastga tekshiriladi:

def songa_aylantir(matn)
  begin
    Integer(matn)
  rescue ArgumentError
    puts "'#{matn}' songa aylanmaydi"
  rescue TypeError
    puts "Noto'g'ri tur berildi"
  end
end

songa_aylantir("42")
songa_aylantir("salom")
'salom' songa aylanmaydi

Diqqat: Integer("42") xatosiz 42 qaytardi, shuning uchun hech qanday rescue ishga tushmadi va natija chop etilmadi. Integer("salom") esa ArgumentError chiqardi va mos rescue uni ushladi. (String#to_i dan farqli, Integer() funksiyasi noto’g’ri matnda sokin 0 emas, aynan xato chiqaradi — bu ataylab tanlangan, qat’iyroq usul.)

ensure — har doim bajariladigan blok

ensure — xato yuz bersa ham, bermasa ham har doim bajariladigan kod uchun ishlatiladi, odatda resurslarni tozalash uchun:

begin
  puts "Fayl ochilmoqda..."
  raise "Ulanish uzildi"
rescue => xato
  puts "Xato: #{xato.message}"
ensure
  puts "Fayl yopildi"
end
Fayl ochilmoqda...
Xato: Ulanish uzildi
Fayl yopildi

raise "Ulanish uzildi" — o’zimiz qo’lda xato chiqardik (RuntimeError turida). ensure bloki xato ushlanganidan keyin ham ishladi — u fayl yopish, ulanishni uzish kabi “albatta bajarilishi kerak” amallar uchun mo’ljallangan.

O’z xato klassingizni yaratish

Katta loyihalarda o’ziga xos xatolarni aniqroq ifodalash uchun StandardErrordan meros oluvchi maxsus klass yaratiladi:

class BalansYetarsizXatosi < StandardError
  def initialize(xabar = "Balansda yetarli mablag' yo'q")
    super
  end
end

def pul_yechish(balans, summa)
  raise BalansYetarsizXatosi if summa > balans
  balans - summa
end

begin
  pul_yechish(1000, 5000)
rescue BalansYetarsizXatosi => xato
  puts "Amaliyot rad etildi: #{xato.message}"
end
Amaliyot rad etildi: Balansda yetarli mablag' yo'q

BalansYetarsizXatosi < StandardError — o’zining nomlangan xato turi, rescueda aynan shu turni alohida ushlash mumkin. Bu, umumiy rescuega solishtirganda, xatoning aynan qaysi biznes-qoida buzilganini aniq ko’rsatadi.