Error turlari va xatolarni boshqarish — try, catch, finally, custom error
Muammodan boshlaylik
Kod har doim kutilganday ishlamaydi. Server javob bermaydi. Foydalanuvchi son o'rniga matn kiritadi. Fayl topilmaydi. Massivda element yo'q.
Agar xato ushlashmasangiz — JavaScript dasturni to'xtatadi. Hamma narsa muzlaydi.
Lekin yaxshi ilova xato bo'lganda ham ishlashda davom etadi. Foydalanuvchiga tushunarli xabar ko'rsatadi. Muhim operatsiyalarni qayta urinib ko'radi. Bu — xatolarni boshqarish (error handling).
JavaScript xato turlari
JavaScript da bir nechta o'rnatilgan xato turi bor. Har biri o'z holati uchun:
TypeError — noto'g'ri tur. null ga xususiyat murojaati, funksiya bo'lmagan narsani chaqirish:
null.ism; // TypeError: Cannot read properties of null
undefined.length; // TypeError
"matn"(); // TypeError: "matn" is not a function
ReferenceError — e'lon qilinmagan o'zgaruvchi:
console.log(yoqOzgaruvchi); // ReferenceError: yoqOzgaruvchi is not defined
SyntaxError — kod sintaksisi noto'g'ri:
eval("if (true {"); // SyntaxError: Unexpected token '{'
RangeError — qiymat ruxsat etilgan oraliqdan tashqarida:
new Array(-1); // RangeError: Invalid array length
(1.5).toFixed(200); // RangeError
URIError — URI funktsiyasida noto'g'ri argument:
decodeURIComponent("%"); // URIError
Har xato ob'ektida ikki asosiy xususiyat bor: message (nima bo'ldi) va stack (qayerda bo'ldi).
try/catch — xatoni ushlab olish
try blokida xato chiqsa — catch ga tushadi. Dastur to'xtamaydi.
try {
const natija = JSON.parse("bu json emas");
} catch (xato) {
console.error("JSON noto'g'ri:", xato.message);
}
console.log("Dastur ishlashda davom etmoqda"); // ← chiqadi
Hayotiy o'xshatma
Alpinist. Tog'ga chiqmoqda. try — urinish. Agar yiqilsa (catch) — jarohatsiz omon qolish uchun xavfsizlik tizimi bor. Yiqilish halokatga olib kelmaydi — davom etish mumkin.
catch — o'sha xavfsizlik tizimi. Xato "ushlanadi", dastur halok bo'lmaydi.
catch da xato turini tekshirish
Turli xatolar turlicha hal qilinishi mumkin:
async function yukla(url) {
try {
const javob = await fetch(url);
if (!javob.ok) {
throw new Error(`Server xatosi: ${javob.status}`);
}
return await javob.json();
} catch (xato) {
if (xato instanceof TypeError) {
// Tarmoq uzilishi — fetch o'zi TypeError chiqaradi
console.error("Internet yo'q yoki server topilmadi");
} else if (xato instanceof SyntaxError) {
// JSON parse xatosi
console.error("Server noto'g'ri JSON yubordi");
} else {
// Boshqa xato — bizning throw qilganimiz
console.error(xato.message);
}
return null;
}
}
finally — har holda
finally — try muvaffaqiyatli tugasa ham, catch ishlasa ham — har holda ishlaydi.
async function ma'lumotOlish() {
let yuklanmoqda = true;
spinnerKo'rsat();
try {
const javob = await fetch("/api/data");
return await javob.json();
} catch (xato) {
xatoBoshqar(xato);
return null;
} finally {
yuklanmoqda = false;
spinnerYashir(); // ← xato bo'lsa ham, bo'lmasa ham — spinner o'chadi
}
}
finally ning eng muhim qoidasi: try da return bo'lsa ham — finally ishlaydi:
function test() {
try {
return "try dan qaytish";
} finally {
console.log("finally ishladi!"); // ← return bo'lsa ham chiqadi
}
}
const natija = test();
// "finally ishladi!"
console.log(natija); // "try dan qaytish"
throw — o'z xatomizni chiqarish
Biz ham istaganmizda xato "otib" yuborish (throw) mumkin. Har qanday qiymat — lekin odatda Error ob'ekti:
function bo'lish(a, b) {
if (b === 0) {
throw new Error("Nolga bo'lish mumkin emas");
}
return a / b;
}
try {
bo'lish(10, 0);
} catch (xato) {
console.error(xato.message); // "Nolga bo'lish mumkin emas"
}
Custom Error — o'z xato sinflari
Turli xato turlarini ajratish uchun — o'z xato sinflarini yaratish mumkin. Bu xatoni instanceof bilan farqlashga imkon beradi.
Hayotiy o'xshatma
Kasalxona. Har kasallikning o'z diagnostika varaqasi bor. "Bemor kasalligi bor" emas — "Yurak kasalligi #42" deyiladi. Har xil kasallik — har xil davolash. Custom Error — o'sha aniq diagnostika.
// Asosiy xato sinfi
class IlovaXatosi extends Error {
constructor(xabar, kod) {
super(xabar);
this.name = "IlovaXatosi";
this.kod = kod;
}
}
// Maxsus xato turlari
class TarmoqXatosi extends IlovaXatosi {
constructor(xabar) {
super(xabar, "TARMOQ_XATOSI");
this.name = "TarmoqXatosi";
}
}
class AuthXatosi extends IlovaXatosi {
constructor() {
super("Tizimga kirish talab qilinadi", "AUTH_XATOSI");
this.name = "AuthXatosi";
}
}
class ValidationXatosi extends IlovaXatosi {
constructor(maydon, xabar) {
super(xabar, "VALIDATSIYA_XATOSI");
this.name = "ValidationXatosi";
this.maydon = maydon;
}
}
Ishlatish:
async function foydalanuvchiYarat(ma'lumot) {
if (!ma'lumot.email) {
throw new ValidationXatosi("email", "Email kiritilmagan");
}
if (!ma'lumot.email.includes("@")) {
throw new ValidationXatosi("email", "Email noto'g'ri formatda");
}
try {
const javob = await fetch("/api/users", {
method: "POST",
body: JSON.stringify(ma'lumot),
});
if (javob.status === 401) throw new AuthXatosi();
if (!javob.ok) throw new TarmoqXatosi(`Server xatosi: ${javob.status}`);
return await javob.json();
} catch (xato) {
if (xato instanceof AuthXatosi) {
loginSahifagaYuborish();
} else if (xato instanceof ValidationXatosi) {
formadaXatoKo'rsat(xato.maydon, xato.message);
} else if (xato instanceof TarmoqXatosi) {
xabarBerish("Tarmoqda muammo bor, qayta urinib ko'ring");
} else {
throw xato; // ← kutilmagan xato — yuqoriga uzatish
}
}
}
instanceof bilan har xato turi aniq ajratildi. Har birining o'z davolash usuli.
Xatoni yuqoriga uzatish — re-throw
Agar catch da xatoni to'liq hal qila olmasangiz — uni yuqoriga "uzatish" kerak. Yutib yubormaslik:
async function yukla() {
try {
return await fetch("/api");
} catch (xato) {
if (xato instanceof TypeError) {
// Tarmoq xatosi — biz hal qilamiz
return keshdan();
}
// Boshqa xatolar — biz bilmaymiz, yuqoriga
throw xato;
}
}
throw xato — xatoni "yutib" yubormaslik. Siz hal qilolmagan xato yuqoridagi catch ga yetadi.
Tez-tez uchraydigan xatolar
Barcha xatoni bir xil ko'rsatish:
// ❌ — har qanday xato uchun bir xil xabar
catch (xato) {
alert("Xato yuz berdi"); // foydalanuvchi nima qilishini bilmaydi
}
// ✅ — xato turiga qarab munosib javob
catch (xato) {
if (xato instanceof ValidationXatosi) {
formadaKo'rsat(xato.message); // foydalanuvchi tuzatishi mumkin
} else if (xato instanceof TarmoqXatosi) {
"Qayta urinib ko'ring"; // vaqtinchalik muammo
} else {
"Kutilmagan xato, murojaat qiling"; // bizning xatoimiz
}
}
Asinxron xatoni try/catch siz qoldirish:
// ❌ — async funksiyadan xato ushlashsiz
async function yukla() {
const data = await fetch("/api"); // xato bo'lsa — unhandled rejection
}
// ✅
async function yukla() {
try {
const data = await fetch("/api");
} catch (xato) {
// ...
}
}
Xulosa
JavaScript da o'rnatilgan xato turlari: TypeError, ReferenceError, SyntaxError, RangeError.
try/catch — xatoni ushlab olish, dastur to'xtamaydi. finally — har holda, resurslarni tozalash uchun.
throw — o'z xatomizni chiqarish. Custom Error — Error dan meros olib, xato turlarini ajratish.
instanceof — catch da xato turini aniqlash. Kutilmagan xatoni throw xato bilan yuqoriga uzatish.
Keyingi dars
64-dars: Regular Expression — asoslar va amaliyot