GoDasturchi
The Error That Got Swallowed

The Error That Got Swallowed

Yutib yuborilgan xato

Tutun signalizatorini (smoke detector) tasavvur qiling: uning batareyasi tugab qolgan, lekin hech kim almashtirmagan — u endi hech qachon signal bermaydi. Uy egasi buni bilmaydi, chunki HAMMASI tashqi ko'rinishda odatdagidek. Yong'in boshlansa, signalizator jim turaveradi, va kichik yong'in katta falokatga aylanadi — chunki uni ERTA aniqlaydigan tizim SASSIZ ishdan chiqqan edi. Kodda "yutib yuborilgan xato" — aynan shunday jim ishdan chiqqan signalizator.

Quyidagi kod review'ga yuborilgan: "Foydalanuvchi balansini yangilaydi va natijani qaytaradi."

balance.go
func UpdateBalance(db *sql.DB, userID string, amount int) error {
	_, err := db.Exec(
		"UPDATE accounts SET balance = balance + ? WHERE id = ?",
		amount, userID,
	)
	if err != nil {
		log.Println("balance update failed:", err)
	}
	return nil
}

Bu kod, birinchi qarashda, "yaxshi" ko'rinadi: err tekshirilgan, hatto jurnalga (log.Println) yozilgan ham. Lekin diqqat bilan qarang — funksiyaning oxirida, errning qiymatidan QAT'IY NAZAR, doim return nil qaytariladi. Ya'ni: agar baza xatosi bo'lsa ham, funksiya chaqiruvchisiga "hammasi joyida, muvaffaqiyatli" deb XABAR beradi.

  • Chaqiruvchi kod if err := UpdateBalance(...); err != nil { ... } deb yozgan bo'lishi mumkin — lekin err HECH QACHON nildan boshqa bo'lmaydi, shuning uchun bu tekshiruv HECH QACHON ishlamaydi
  • Baza vaqtincha ishlamay qolsa (tarmoq nosozligi, ulanish tugashi), foydalanuvchi balansi YANGILANMAYDI, lekin ilova "muvaffaqiyatli" deb hisoblab, foydalanuvchiga "balansingiz yangilandi" deb ko'rsatishi mumkin
  • Bu xato — Go Basics va Error Handling kurslarida ko'rgan "xatoni tekshirish yetarli emas, uni TO'G'RI ISHLATISH kerak" tamoyilining buzilishi: err != nil tekshirilgan, lekin natija E'TIBORGA olinmagan

To'g'ri kod — log.Println dan keyin, xatoni CHAQIRUVCHIGA ham qaytarish kerak: if err != nil { return fmt.Errorf("update balance: %w", err) }. Bu — Error Handling kursida ko'rgan %w bilan xatoni O'RASH (wrapping) orqali, sababni yo'qotmasdan yuqoriga uzatish.

Review'da bu turdagi xatoni topishning kaliti — funksiya IMZOSI (error qaytarishi) bilan uning TANASI (har doim nil qaytarishi) orasidagi NOMUVOFIQLIKKA e'tibor berish. Agar funksiya error qaytarsa, lekin ba'zi yo'llarda bu xato HECH QACHON haqiqiy qiymat bo'lib qaytmasa — bu shubhali belgi, albatta chuqurroq tekshirish kerak.

Key Takeaway

Key Takeaway:

Xatoni jurnalga yozish, uni chaqiruvchiga QAYTARISH bilan bir xil emas. Funksiya error qaytarsa-yu, uning tanasida har doim nil qaytarilsa — bu xato jimgina yutib yuborilyapti, va chaqiruvchi hech qachon muammodan xabar topmaydi.

NEXT UP

The Race Hiding in Two Goroutines

The Error That Got Swallowed

Yutib yuborilgan xato

Tutun signalizatorini (smoke detector) tasavvur qiling: uning batareyasi tugab qolgan, lekin hech kim almashtirmagan — u endi hech qachon signal bermaydi. Uy egasi buni bilmaydi, chunki HAMMASI tashqi ko'rinishda odatdagidek. Yong'in boshlansa, signalizator jim turaveradi, va kichik yong'in katta falokatga aylanadi — chunki uni ERTA aniqlaydigan tizim SASSIZ ishdan chiqqan edi. Kodda "yutib yuborilgan xato" — aynan shunday jim ishdan chiqqan signalizator.

Quyidagi kod review'ga yuborilgan: "Foydalanuvchi balansini yangilaydi va natijani qaytaradi."

balance.go
func UpdateBalance(db *sql.DB, userID string, amount int) error {
	_, err := db.Exec(
		"UPDATE accounts SET balance = balance + ? WHERE id = ?",
		amount, userID,
	)
	if err != nil {
		log.Println("balance update failed:", err)
	}
	return nil
}

Bu kod, birinchi qarashda, "yaxshi" ko'rinadi: err tekshirilgan, hatto jurnalga (log.Println) yozilgan ham. Lekin diqqat bilan qarang — funksiyaning oxirida, errning qiymatidan QAT'IY NAZAR, doim return nil qaytariladi. Ya'ni: agar baza xatosi bo'lsa ham, funksiya chaqiruvchisiga "hammasi joyida, muvaffaqiyatli" deb XABAR beradi.

  • Chaqiruvchi kod if err := UpdateBalance(...); err != nil { ... } deb yozgan bo'lishi mumkin — lekin err HECH QACHON nildan boshqa bo'lmaydi, shuning uchun bu tekshiruv HECH QACHON ishlamaydi
  • Baza vaqtincha ishlamay qolsa (tarmoq nosozligi, ulanish tugashi), foydalanuvchi balansi YANGILANMAYDI, lekin ilova "muvaffaqiyatli" deb hisoblab, foydalanuvchiga "balansingiz yangilandi" deb ko'rsatishi mumkin
  • Bu xato — Go Basics va Error Handling kurslarida ko'rgan "xatoni tekshirish yetarli emas, uni TO'G'RI ISHLATISH kerak" tamoyilining buzilishi: err != nil tekshirilgan, lekin natija E'TIBORGA olinmagan

To'g'ri kod — log.Println dan keyin, xatoni CHAQIRUVCHIGA ham qaytarish kerak: if err != nil { return fmt.Errorf("update balance: %w", err) }. Bu — Error Handling kursida ko'rgan %w bilan xatoni O'RASH (wrapping) orqali, sababni yo'qotmasdan yuqoriga uzatish.

Review'da bu turdagi xatoni topishning kaliti — funksiya IMZOSI (error qaytarishi) bilan uning TANASI (har doim nil qaytarishi) orasidagi NOMUVOFIQLIKKA e'tibor berish. Agar funksiya error qaytarsa, lekin ba'zi yo'llarda bu xato HECH QACHON haqiqiy qiymat bo'lib qaytmasa — bu shubhali belgi, albatta chuqurroq tekshirish kerak.

Key Takeaway

Key Takeaway:

Xatoni jurnalga yozish, uni chaqiruvchiga QAYTARISH bilan bir xil emas. Funksiya error qaytarsa-yu, uning tanasida har doim nil qaytarilsa — bu xato jimgina yutib yuborilyapti, va chaqiruvchi hech qachon muammodan xabar topmaydi.

NEXT UP

The Race Hiding in Two Goroutines