11-bo‘lim
Xatoliklarni boshqarish
try/catch/finally, xato turlari, throw, o'z xato sinflaringiz, xatolarni to'g'ri ushlash va tuzatish usullari.
Ushbu bo‘lim mundarijasi
Xato bo'lishi muqarrar. Yaxshi dastur xatoni kutadi va uni foydalanuvchiga tushunarli qilib ko'rsatadi.
try / catch / finally #
function boluvchi(a, b) {
try {
if (b === 0) {
throw new Error("Nolga bo'lish mumkin emas");
}
return a / b;
} catch (xato) {
console.log("Xato ushlandi:", xato.message);
return null;
} finally {
console.log(" (finally har doim ishlaydi)");
}
}
console.log("Natija:", boluvchi(10, 2));
console.log("Natija:", boluvchi(10, 0));
(finally har doim ishlaydi)
Natija: 5
Xato ushlandi: Nolga bo'lish mumkin emas
(finally har doim ishlaydi)
Natija: null
Xato turlari #
const sinovlar = [
() => { null.xossa; },
() => { mavjudEmas(); },
() => { JSON.parse("{buzuq}"); },
() => { const x = 1; x = 2; },
() => { new Array(-1); },
() => { decodeURIComponent("%"); }
];
for (const sinov of sinovlar) {
try {
sinov();
} catch (xato) {
console.log(`${xato.name.padEnd(14)} ${xato.message.slice(0, 42)}`);
}
}
TypeError Cannot read properties of null (reading 'x
ReferenceError mavjudEmas is not defined
SyntaxError Expected property name or '}' in JSON at p
TypeError Assignment to constant variable.
RangeError Invalid array length
URIError URI malformed
| Tur | Qachon chiqadi |
|---|---|
TypeError | Noto'g'ri turdagi qiymat bilan amal |
ReferenceError | Mavjud bo'lmagan o'zgaruvchi |
SyntaxError | Sintaksis xatosi (odatda JSON.parse) |
RangeError | Ruxsat etilgan oraliqdan tashqarida |
URIError | Noto'g'ri URI kodlash |
throw bilan o'z xatolaringiz #
function yoshTekshirish(yosh) {
if (typeof yosh !== "number") {
throw new TypeError("Yosh son bo'lishi kerak");
}
if (Number.isNaN(yosh)) {
throw new RangeError("Yosh NaN bo'la olmaydi");
}
if (yosh < 0 || yosh > 150) {
throw new RangeError("Yosh 0 dan 150 gacha bo'lishi kerak");
}
return `Yosh qabul qilindi: ${yosh}`;
}
const kirimlar = [25, "yigirma", -5, 200, NaN];
for (const kirim of kirimlar) {
try {
console.log(yoshTekshirish(kirim));
} catch (xato) {
console.log(`${xato.name}: ${xato.message}`);
}
}
Yosh qabul qilindi: 25
TypeError: Yosh son bo'lishi kerak
RangeError: Yosh 0 dan 150 gacha bo'lishi kerak
RangeError: Yosh 0 dan 150 gacha bo'lishi kerak
RangeError: Yosh NaN bo'la olmaydi
throw "matn" yozmangJavaScript istalgan qiymatni tashlashga ruxsat beradi:
throw "Xato yuz berdi"; // ishlaydi, lekin yomon
throw 42; // bu ham
Muammolari:
.messageva.nameyo'q;- Stek izi (stack trace) yo'q - xato qayerdan kelganini bilib bo'lmaydi;
instanceof Errorfalseqaytaradi.
Har doim Error yoki uning vorisini tashlang:
throw new Error("Xato yuz berdi");
Ushlaganda ham ehtiyot bo'ling - boshqa kutubxona satr tashlagan bo'lishi mumkin:
catch (xato) {
const xabar = xato instanceof Error ? xato.message : String(xato);
}
O'z xato sinfingiz #
class ValidatsiyaXatosi extends Error {
constructor(maydon, xabar) {
super(xabar);
this.name = "ValidatsiyaXatosi";
this.maydon = maydon;
}
}
class TarmoqXatosi extends Error {
constructor(kod, xabar) {
super(xabar);
this.name = "TarmoqXatosi";
this.kod = kod;
}
}
function formaniTekshirish(malumot) {
if (!malumot.email) {
throw new ValidatsiyaXatosi("email", "Email kiritilmagan");
}
if (!malumot.email.includes("@")) {
throw new ValidatsiyaXatosi("email", "Email formati noto'g'ri");
}
return true;
}
const sinovlar = [{}, { email: "salom" }, { email: "[email protected]" }];
for (const sinov of sinovlar) {
try {
formaniTekshirish(sinov);
console.log("To'g'ri:", sinov.email);
} catch (xato) {
if (xato instanceof ValidatsiyaXatosi) {
console.log(`[${xato.maydon}] ${xato.message}`);
} else {
throw xato;
}
}
}
const tarmoq = new TarmoqXatosi(404, "Topilmadi");
console.log("Error vorisimi?:", tarmoq instanceof Error);
console.log("Kod :", tarmoq.code ?? tarmoq.kod);
[email] Email kiritilmagan
[email] Email formati noto'g'ri
To'g'ri: [email protected]
Error vorisimi?: true
Kod : 404
O'z sinflaringiz ushlash mantiqini aniqlashtiradi:
try {
await sorovYuborish();
} catch (xato) {
if (xato instanceof ValidatsiyaXatosi) {
maydonniBelgilash(xato.maydon); // foydalanuvchiga ko'rsatish
} else if (xato instanceof TarmoqXatosi) {
qaytaUrinish(); // avtomatik takrorlash
} else {
throw xato; // notanish - yuqoriga uzatish
}
}
Muhim qoida: tanimagan xatoni qayta tashlang. Aks holda haqiqiy dastur xatosi jimgina yo'qoladi va uni topish juda qiyin bo'ladi.
Xatoni yutib yuborish - eng yomon odat #
// YOMON - xato yo'qoladi
function yomon(matn) {
try {
return JSON.parse(matn);
} catch (xato) {
return null; // nima bo'lgani noma'lum
}
}
// YAXSHI - sabab saqlanadi
function yaxshi(matn) {
try {
return { ok: true, malumot: JSON.parse(matn) };
} catch (xato) {
return { ok: false, sabab: xato.message };
}
}
console.log("Yomon :", yomon("{buzuq}"));
const natija = yaxshi("{buzuq}");
console.log("Yaxshi :", natija.ok, "-", natija.sabab.slice(0, 30));
const togri = yaxshi('{"ism":"Aziza"}');
console.log("To'g'ri:", togri.ok, "-", togri.malumot.ism);
Yomon : null
Yaxshi : false - Expected property name or '}'
To'g'ri: true - Aziza
catch blokini yozmangtry {
xavfliAmal();
} catch (xato) {
// hech nima
}
Bu kod xatoni butunlay yashiradi. Dastur noto'g'ri ishlaydi, lekin siz nima uchunligini hech qachon bilmaysiz.
Agar xato haqiqatan ahamiyatsiz bo'lsa, buni izohda yozing:
try {
localStorage.setItem("kalit", qiymat);
} catch (xato) {
// Maxfiy rejimda localStorage taqiqlangan - bu normal holat
}
Aks holda kamida jurnalga yozing:
catch (xato) {
console.error("Saqlab bo'lmadi:", xato);
}
finally va return #
function sinov() {
try {
return "try dan";
} finally {
console.log(" finally ishladi");
}
}
console.log(sinov());
// finally ichida return - try ning natijasini BOSIB O'TADI
function xavfli() {
try {
return "try dan";
} finally {
return "finally dan"; // try ning qiymatini yo'q qiladi
}
}
console.log(xavfli());
finally ishladi
try dan
finally dan
finally ichida return yozmangYuqoridagi xavfli() funksiya har doim "finally dan"
qaytaradi - try dagi return yo'qoladi.
Undan ham yomoni: finally dagi return tashlangan xatoni
ham yutib yuboradi:
function juda_xavfli() {
try {
throw new Error("muhim xato");
} finally {
return "hammasi joyida"; // xato yo'qoldi!
}
}
Bu funksiya xato tashlamaydi va muammo butunlay ko'rinmay qoladi.
finally faqat tozalash uchun: fayl yopish, ulanishni
uzish, yuklanish belgisini o'chirish.
Amaliy naqsh: qayta urinish #
function beqarorAmal(urinish) {
if (urinish < 3) {
throw new Error(`${urinish}-urinish muvaffaqiyatsiz`);
}
return "muvaffaqiyat";
}
function qaytaUrinish(amal, maksUrinish = 5) {
const xatolar = [];
for (let i = 1; i <= maksUrinish; i++) {
try {
const natija = amal(i);
console.log(`${i}-urinishda o'tdi`);
return natija;
} catch (xato) {
xatolar.push(xato.message);
console.log(` ${xato.message}`);
}
}
throw new Error(`${maksUrinish} urinish behuda: ${xatolar.length} xato`);
}
console.log("Natija:", qaytaUrinish(beqarorAmal));
try {
qaytaUrinish(() => { throw new Error("doimiy xato"); }, 2);
} catch (xato) {
console.log("Yakuniy:", xato.message);
}
1-urinish muvaffaqiyatsiz
2-urinish muvaffaqiyatsiz
3-urinishda o'tdi
Natija: muvaffaqiyat
doimiy xato
doimiy xato
Yakuniy: 2 urinish behuda: 2 xato
Xato sababini saqlash #
function malumotOqish(matn) {
try {
return JSON.parse(matn);
} catch (xato) {
throw new Error("Sozlama faylini o'qib bo'lmadi", { cause: xato });
}
}
try {
malumotOqish("{buzuq}");
} catch (xato) {
console.log("Xabar :", xato.message);
console.log("Sabab :", xato.cause.name);
console.log("Batafsil:", xato.cause.message.slice(0, 30));
}
Xabar : Sozlama faylini o'qib bo'lmadi
Sabab : SyntaxError
Batafsil: Expected property name or '}'
cause - xatolar zanjiriES2022 dan Error ning ikkinchi argumenti bor:
new Error("yuqori darajadagi xabar", { cause: aslXato });
Bu ikki dunyoni birlashtiradi:
- Foydalanuvchiga tushunarli xabar;
- Dasturchiga kerakli texnik tafsilot.
Ilgari buni qo'lda qilishga to'g'ri kelardi:
const yangi = new Error("xabar");
yangi.original = aslXato; // nostandart
Endi cause standart va console.error uni avtomatik
ko'rsatadi.
Server jurnalida to'liq zanjirni ko'rsating, foydalanuvchiga esa faqat yuqori darajadagi xabarni - texnik tafsilot xavfsizlik ma'lumotini oshkor qilishi mumkin.
try/catch/finallyuchalasi qachon ishlashini ko'rsating.- Beshta xato turini ataylab chiqarib, nomlarini chop eting.
throw new Errorvathrow "matn"farqini tushuntiring.ValidatsiyaXatosisinfini yozing vainstanceofbilan ushlang.- Tanimagan xatoni qayta tashlash nima uchun muhimligini ayting.
- Bo'sh
catchblokining zararini misolda ko'rsating. finallyichidagireturnxatoni yutishini isbotlang.- Qayta urinish funksiyasini yozing.
causebilan xatolar zanjirini tuzing.{ ok, malumot }naqshi bilan xavfsizJSON.parseyozing.
Xulosa #
tryxatoli kodni,catchxatoni,finallytozalashni oladi.finallyhar doim ishlaydi -returndan keyin ham.- Asosiy turlar:
TypeError,ReferenceError,SyntaxError,RangeError. throw new Erroryozing - satr tashlamang.- O'z xato sinflaringiz ushlash mantiqini aniqlashtiradi.
- Tanimagan xatoni qayta tashlang - yutib yubormang.
- Bo'sh
catch- eng yomon odat; kamida jurnalga yozing. finallyichidareturnyozmang - xatoni yutadi.causebilan asl xatoni saqlang.- Foydalanuvchiga sodda xabar, jurnalga to'liq zanjir.
Keyingi bo'limda DOM bilan tanishib, sahifani boshqarishni boshlaymiz.
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.