Section 11

11-dars — Xatolarni boshqarish

error tipi, err != nil, nil, errors.New, panic — Go uslubidagi xato boshqaruvi


O'tgan darsda _ bilan xatolarni e'tiborsiz qoldirdik. Bu xavfli edi: fayl bo'lmasa balans noto'g'ri (0) bo'lardi. Bu darsda Go'ning xato boshqarish uslubini o'rganamiz — bu Go'ning eng muhim g'oyalaridan biri.

Go'da xato qanday ishlaydi?

Boshqa tillarda (Java, Python, JavaScript) xato "tashlanadi" va try-catch bilan ushlanadi. Go'da bunday mexanizm yo'q. Go'da xato — oddiy qiymat: funksiya natija bilan birga error qiymatini ham qaytaradi. Sizning vazifangiz — uni tekshirish.

Yaxshi tomoni: xato bo'lsa ham dastur qulab tushmaydi — masalan os.ReadFile fayl topilmasa, bo'sh ma'lumot va xato qaytaradi, dasturni ishdan chiqarmaydi.

data, err := os.ReadFile(accountBalanceFile)

err — xato qiymati. Hammasi joyida bo'lsa, err = nil ("xato yo'q"). Muammo bo'lsa, err ichida xabar bo'ladi.


nil va err != nil — asosiy naqsh

nil — Go'dagi maxsus qiymat: "qiymat yo'q", "bo'sh". Go kodida eng ko'p uchraydigan qator:

if err != nil {
	// xato bor — uni hal qilamiz
}

err != nil — "xato bormi?" degan savol. Buni o'z funksiyamizda qo'llaymiz:

import (
	"errors"
	"fmt"
	"os"
	"strconv"
)
 
const accountBalanceFile = "balance.txt"
 
func getBalanceFromFile() (float64, error) {
	data, err := os.ReadFile(accountBalanceFile)
 
	if err != nil {
		return 1000, errors.New("Failed to find balance file.")
	}
 
	balanceText := string(data)
	balance, err := strconv.ParseFloat(balanceText, 64)
 
	if err != nil {
		return 1000, errors.New("Failed to parse stored balance value.")
	}
 
	return balance, nil
}

Tushuntirish

  • (float64, error) — funksiya endi ikki narsa qaytaradi: balans va xato. Qoida: xato har doim oxirgi qaytarish qiymati bo'ladi.
  • errors.New("...") — yangi xato yaratadi (matn bilan). Buning uchun errors paketini import qilamiz.
  • return 1000, errors.New(...) — muammo bo'lsa: standart 1000 va xatoni tushuntiramiz.
  • return balance, nil — hammasi joyida bo'lsa: balans va nil (xato yo'q).

os.ReadFile va strconv.ParseFloat — ikkalasi ham xato qaytarishi mumkin, shuning uchun ikkalasini ham tekshiramiz.


Chaqirgan joyda tekshirish

func main() {
	var accountBalance, err = getBalanceFromFile()
 
	if err != nil {
		fmt.Println("ERROR")
		fmt.Println(err)
		fmt.Println("---------")
	}
 
	// ... bank ishini davom ettiramiz (accountBalance = 1000)
}

fmt.Println(err) xatoning xabarini avtomatik chiqaradi. Endi balance.txt bo'lmasa, dastur xatoni ko'rsatadi, lekin (standart 1000 bilan) ishlashda davom etadi.


panic qachon?

Ba'zan xato shu qadar jiddiyki, davom etishning ma'nosi yo'q. Shunda panic ishlatiladi — u dasturni darhol to'xtatadi (qulatadi) va xato izini (qaysi qatorda yuz bergani) chiqaradi:

panic("Can't continue, sorry.")

return bilan farqi: return dasturdan toza chiqadi; panic esa "qulash" (crash) — qo'shimcha xato izini (stack trace) ko'rsatadi, bu xatoni topishga yordam beradi.

Ehtiyot bo'ling: panic — kuchli vosita. Ko'p hollarda xatoni if err != nil bilan muloyim hal qilish to'g'riroq. panic ni faqat haqiqatan tuzatib bo'lmaydigan holatlarga qoldiring.


Bo'lim mashqi: validatsiya + faylga saqlash

4-darsdagi profit kalkulyatorni yakunlaymiz. Ikki vazifa:

1) Kiritishni tekshirish: manfiy yoki nol qiymatga xato yaratib, main da uni boshqarish.

func getUserInput(infoText string) (float64, error) {
	var userInput float64
	fmt.Print(infoText)
	fmt.Scan(&userInput)
 
	if userInput <= 0 {
		return 0, errors.New("Value must be a positive number.")
	}
 
	return userInput, nil
}

main da har chaqiruvdan keyin tekshiramiz (har birini alohida tekshirish kerak — aks holda faqat oxirgi err saqlanib qoladi):

revenue, err := getUserInput("Revenue: ")
if err != nil {
	fmt.Println(err)
	return
}

2) Natijalarni faylga saqlash (os va Sprintf bilan):

func storeResults(ebt, profit, ratio float64) {
	results := fmt.Sprintf("EBT: %.1f\nProfit: %.1f\nRatio: %.3f\n", ebt, profit, ratio)
	os.WriteFile("results.txt", []byte(results), 0644)
}

va main oxirida storeResults(ebt, profit, ratio) deb chaqiramiz.


O'zingiz sinab ko'ring

  1. getBalanceFromFile ni (float64, error) qaytaradigan qilib qayta yozing.
  2. main da err != nil bilan tekshiruv qo'shing.
  3. balance.txt ni o'chirib dasturni ishga tushiring — xato xabaringiz chiqdimi?
  4. getUserInput ga validatsiya qo'shing, manfiy son kiritib sinab ko'ring.
  5. storeResults ni yozib, results.txt paydo bo'lganini tekshiring.

10-dars · Boshiga qaytish