Pri izvajanju kode JavaScript lahko pride do različnih napak. Napaka je lahko posledica napačno zapisane kode, neustreznega uporabniškega vnosa ali nepričakovane situacije med izvajanjem programa. Za obravnavo napak JavaScript uporablja stavke try, catch, throw in finally. Ti omogočajo, da program napako zazna, jo obdela in po potrebi nadaljuje izvajanje na nadzorovan način.
Pomni: V sodobni kodi je praviloma priporočljivo, da z ukazom throw sprožimo objekt Error ali njegovo podvrsto, ne pa navadnega niza. Objekt Error vsebuje vsaj podatke name in message, po potrebi pa tudi cause.
Osnovna pravila
- Blok
tryvsebuje kodo, v kateri lahko pride do napake. - Blok
catchvsebuje kodo, ki se izvede, če je v blokutrysprožena napaka. - Stavek
throwomogoča namensko sprožanje napake. - Blok
finallyse izvede ne glede na to, ali je do napake prišlo ali ne. - Pri lastnih napakah je v sodobni kodi priporočljiva uporaba objektov
Error.
Primerjave
try in catch
Stavek try...catch uporabljamo takrat, ko želimo nadzorovati izvajanje kode, v kateri bi se lahko pojavila napaka. Če se v bloku try sproži izjema, se izvajanje prenese v blok catch. Če se napaka ne sproži, se blok catch preskoči. Bloka try in catch morata biti zapisana kot bloka v zavitih oklepajih.
try {
koda, ki jo preverjamo;
} catch (napaka) {
koda, ki se izvede ob napaki;
}
Primer, kjer je v kodi napaka v imenu funkcije:
<p id="primer1"></p>
<script>
try {
prommmpt("Vnesi starost:");
} catch (err) {
document.getElementById("primer1").textContent = err.message;
}
</script>
Pozor: Stavek try...catch obravnava napake, ki nastanejo med izvajanjem kode. Ne nadomesti pa premišljenega načrtovanja programa in ne odpravlja vseh logičnih napak v kodi.
throw
Stavek throw omogoča, da napako sprožimo sami. Ko JavaScript izvede throw, se izvajanje trenutne funkcije takoj prekine, nadzor pa preide do najbližjega ustreznega bloka catch. Če takega bloka ni, se izvajanje programa prekine.
throw izraz;
Starejša gradiva pogosto kažejo tudi primere, kjer se sproži niz, število ali logična vrednost:
throw "Napaka";
throw 48;
throw false;
Takšen zapis je sicer veljaven, vendar v sodobni kodi praviloma raje sprožimo objekt Error, ker ta vsebuje več uporabnih podatkov.
Primer preverjanja vnosa v besedilno polje z uporabo throw:
<p>Vnesi številko meseca od 1 do 12:</p>
<input id="polje" type="text" size="3">
<button type="button" onclick="mesec()">Vnesi</button>
<p id="info"></p>
<script>
function mesec() {
let info = document.getElementById("info");
let x = document.getElementById("polje").value;
info.textContent = "";
try {
if (x === "") throw new Error("Vnesena vrednost je prazna.");
if (isNaN(x)) throw new Error("Vnesena vrednost ni število.");
x = Number(x);
if (x < 1) throw new Error("Vnesena vrednost je prenizka.");
if (x > 12) throw new Error("Vnesena vrednost je previsoka.");
info.textContent = "Vnos je pravilen.";
} catch (napaka) {
info.textContent = napaka.message;
}
}
</script>
Vnesi številko meseca od 1 do 12:
finally
Blok finally vsebuje kodo, ki se izvede ne glede na to, ali je do napake prišlo ali ne. Običajno ga uporabljamo za čiščenje stanja programa, zapiranje virov, ponastavljanje vmesnika ali druge zaključne korake. Izvede se, preden program zapusti celotno konstrukcijo try...catch...finally.
try {
koda, ki jo preverjamo;
} catch (err) {
koda, ki se izvede ob napaki;
} finally {
koda, ki se izvede v vsakem primeru;
}
Primer, kjer blok finally po preverjanju vedno počisti vnosno polje:
<p>Vnesi številko meseca od 1 do 12:</p>
<input id="polje1" type="text" size="3">
<button type="button" onclick="mesec1()">Vnesi</button>
<p id="info1"></p>
<script>
function mesec1() {
let info1 = document.getElementById("info1");
let x1 = document.getElementById("polje1").value;
info1.textContent = "";
try {
if (x1 === "") throw new Error("Vnesena vrednost je prazna.");
if (isNaN(x1)) throw new Error("Vnesena vrednost ni število.");
x1 = Number(x1);
if (x1 < 1) throw new Error("Vnesena vrednost je prenizka.");
if (x1 > 12) throw new Error("Vnesena vrednost je previsoka.");
info1.textContent = "Vnos je pravilen.";
} catch (napaka) {
info1.textContent = napaka.message;
} finally {
document.getElementById("polje1").value = "";
}
}
</script>
Vnesi številko meseca od 1 do 12:
Objekt Error
Napake v JavaScriptu so praviloma objekti, ki temeljijo na objektu Error. Tak objekt navadno vsebuje ime napake v lastnosti name in opis v lastnosti message. V sodobni kodi lahko pri ponovnem sprožanju napake uporabimo tudi lastnost cause, s katero ohranimo prvotni vzrok napake.
try {
throw new Error("Prišlo je do napake.");
} catch (err) {
console.log(err.name); // Error
console.log(err.message); // Prišlo je do napake.
}
Pomni: Lastnost stack je zelo uporabna pri razhroščevanju, vendar ni del standardiziranega jedra na enak način kot name in message, zato je ne uporabljamo kot osnovo učne razlage.
Priporočila
- Blok
tryuporabljaj le tam, kjer je napaka dejansko mogoča in jo znaš smiselno obdelati. - Pri lastnih napakah praviloma uporabljaj
throw new Error(...). - V bloku
catchizpisuj ali obdeluj razumljivo sporočilo napake. - Blok
finallyuporabljaj za čiščenje stanja, na primer za praznjenje polj ali zapiranje virov. - Napake obravnavaj čim bliže mestu, kjer jih lahko tudi smiselno popraviš ali prikažeš uporabniku.
Pogoste napake
- V bloku
tryje zajet prevelik del kode, zato je težje ugotoviti, kje je napaka dejansko nastala. - Stavek
throwsproži navaden niz namesto objektaError, zato je napaka manj pregledna in vsebuje manj uporabnih podatkov. - Blok
catchnapako prestreže, vendar ne poda jasnega sporočila ali ne izvede ustrezne obdelave. - Blok
finallyse razume kot del, ki se izvede samo ob napaki, čeprav se izvede v vsakem primeru. - Obravnava napak se uporablja kot nadomestilo za osnovno preverjanje vhodnih podatkov in za premišljeno zasnovo programa.