Kurs: - Core JavaScript Programming Materijali vezani uz ovu lekciju: - Test rukovanje greškama i izuzecima - Rukovanje greškama i izuzecima (PDF dokument) Oktrijmo na početku koje su sve vrste grešaka podrazumevane u programiranju:
• sintaksne greške Greške u kucanju koda. Vide se u trenutku startovanja (interpretacije) skripte. Da govorimo o jeziku koji se kompajlira, mogli bismo još preciznije opisati ove greške jer su to zapravo greške koje nam ne dozvoljavaju čak ni da kompajliramo naš kod. S obzirom na to da se JavaScript interpretira, odnosno, da se praktično kompajlira u trenutku kada se izvršava, ovde će te greške biti prikazane u trenutku izvršavanja (interpretacije). • logičke greške Logičke greške, za razliku od sintaksnih, ne ometaju kod u interpretaciji ili kompajliranju, ali pri tom ne daju ni željene rezultate, što dovoljno govori o tome koliko mogu biti opasne. U nekim okruženjima, ovakve greške se nazivaju još i semantičke greške, dok se u nekim okruženjima pominje još grupa grešaka koje podrazumevaju validno kompajliranje koda, ali probleme prilikom izvršavanja kompajliranog koda (pri čemu se takav vid grešaka u tim okruženjima naziva semantičkim). Do sada smo se, kroz rad više puta susreli sa loše napisanim kodom, koji je izazvao grešku u pretraživaču. Ona se manifestuje žutim trouglom sa uzvičnikom u donjem levom uglu pretraživača, a nakon dvoklika emituje i prozor za bližim informacijama o grešci. Probleme koji izazivaju ove greške potrebno je otkloniti, odnosno, preduprediti prilikom kreiranja koda. To je u najvećem broju slučajeva moguće, ali ponekad i ne. Na primer, u situacijama kada dođe do problema sa dinamičkim podacima od kojih zavisi tok programa (jednostavno ih nema ili nisu u dobrom formatu). Za takve situacije, koristimo poseban mehanizam koji se zove rukovanje izuzecima, odnosno, Exception Handling. Rukovanje izuzecimaRecimo da je kod koji je izazvao grešku sa slike, izgledao ovako:
<script type="text/javascript"> y=x; </script> Očigledno je da je uzrok greške to što promenljiva y traži vrednost iz nepostojeće promenljive x. Da smo negde u kodu napravili podrazumevanu vrednost za x, do greške ne bi došlo. Međutim, ako želimo da x bude vrednost preuzeta sa nekog drugog sajta, iz neke druge skripte, ali da taj sajt trenutno nije u funkciji, morali bismo da napravimo malo ozbiljniji mehanizam za zaštitu od tog problema. Taj mehanizam, mogao bi da podrazumeva i korišćenje izuzetaka. Za rukovanje izuzecima, potrebno nam je da znamo (ili bar pretpostavimo) koji deo koda bi mogao da izazove nepravilnosti u radu. Tkođe bi trebalo da se pobrinemo da, ukoliko bi taj problematični deo koda otkazao, program može da funkcioniše na alternativnom nivou. Kada to saznamo, koristimo try – catch blokove, karakteristične isključivo za rukovanje izuzecima, pri čemu je sadržaj try bloka, ono što bi trebalo da se podrazumevano dogodi, a sadržaj catch bloka - ono što će se dogoditi ukoliko sadržaj try bloka ne bude regularno izvršen. Jedan try catch blok u praksi izgleda ovako: <script type="text/javascript"> Ovaj kod poseduje neke nepomenute osobenosti. Pre svega, primećujemo da blok catch ima i određeni parametar e smešten u male zagrade. Evo šta taj parametar predstavlja: Kada pretraživač registruje nepravilnost u JavaScript kodu, on ne reaguje tako što „ad hok“ emituje grešku na ekran, već stvori objekat tipa Error (greška) u koji smesti sve parametre greške, a zatim, taj Error objekat pročita i neke od njegovih parametara prikaže nam na ekranu (npr. x is undefined). Slično smo uradili i sami u prethodnom kodu. Startovali smo try blok, pokušali da obradimo u njemu promenljivu y što nije išlo, a zatim, startovali alternativni kod u kome smo emitovali poruku da „nije u redu“. Razlika je samo u tome što mi nismo dali opširne podatke o grešci. A upravo ti podaci (bar neki od njih), nalaze se u instanci klase Error, odnosno, objektu e, odnosno njenim atributima (message, description, number, constructor). To znači da, ako preradimo kod i catch bloku umesto alert (parametra "nije u redu"), unesemo kao parametar e.message, dobićemo tačan tekst izazvane greške (x is undefined). Pored toga što ima svoje atribute, greška takođe podrazumeva i određeni tip, pri čemu JavaScript podrazumeva šest ugrađenih tipova grešaka: EvalError (greške prilikom korišćenja eval funkcije), RangeError (tip promenljive ne može da prihvati traženu veličinu vrednosti), ReferenceError (greška pri referenciranju objekata), SyntaxError (greška u kucanju, sintaksna greška), TypeError (pogrešan tip promenljive), URIError (greške u encodeURI i decodeURI funkcijama). Da bismo obradili samo određeni tip greške, potrebno je da u catch blok postavimo uslove za svaki tip koji želimo da obrađujemo. Na primer: <script type="text/javascript"> Grešku možemo i ručno generisati i „izbaciti“. U bilo kom trenutku izvršavanja programa i pod bilo kojim uslovima, ključnom rečju throw (baci). Treba samo obratiti pažnju da grešku nakon „izbacivanja“ i uhvatimo. Najbolji primer za to je sledeći kod: <script type="text/javascript"> U primeru je napravljena funkcija koja izbacuje grešku. Funkcija se nakon toga poziva iz try-catch bloka gde se konačno u catch bloku emituje njen sadržaj. Za razliku od ugrađenih grešaka koje su sadržale i određene atribute, ova, nazovimo je in-line greška, sastoji se samo od teksta greške. Za emitovanje ozbiljnijeg izuzetka, potrebno je da ga definišemo i dodelimo mu određene karakteristike: <script type="text/javascript"> Na način na koji smo dodelili atribut message našem Error objektu, možemo dodeliti i druge atribute (description, name...). Takođe, parametar message, mogli smo proslediti i prilikom konstrukcije objekta: mojaGreska = new Error("ovo je moja greska"); Konačno, namerno smo izostavili jedan blok u try-catch setu. Ovaj blok je opcion i naziva se finally. Finally, u stvari, predstavlja blok za koji želimo da se izvrši u svakom slučaju, bilo da je try blok izvršen neometano ili da je došlo do alternativnog izvršavanja catch bloka - nešto slično kao da smo stavili naredbu nakon završetka try - catch bloka. Ovaj blok naročito je koristan prilikom rukovanja sa resursima kada se u njega stavljaju naredbe za zatvaranje tih resursa da bismo bili sigurni da nakon izvršavanja ni jedan resurs nije ostao otvoren zbog pucanja aplikacije izazvane greškom. S obzirom na to da JavaScript nije u stanju da rukuje resursima direktno, potreba za finally blokom je nešto manja. Evo kako bi izgledao kod sa dodatim finally blokom: <script type="text/javascript"> Događaj greškeRukovanje izuzecima nije jedini način da se u JavaScript-u obradi greška. Svaka greška izazvana u JavaScript kodu izaziva i događaj window objekta, odnosno najvišeg objekta tog dokumenta. Ovaj događaj je moguće takođe obraditi i izbeći pojavu greške:
<script type="text/javascript"> U primeru, aplikacija će emitovati korisnički definisanu poruku greska, a zatim će pretraživač emitovati svoju standardnu poruku greške; što možemo i onemogućiti ukoliko kao povratni parametar funkcije koja obrađuje grešku, postavimo vrednost true. To u ovom slučaju, prosto rečeno, znači da šaljemo poruku pretraživaču da je greška obrađena i da je sve u redu. <script type="text/javascript"> U ovom slučaju pretraživač (JavaScript interpreter) će smatrati da je greška obrađena i neće objavljivati sopstvenu poruku o grešci. Funkcija koju startuje događaj on error događaj može prihvatiti i do tri parametra. Opis greške, fajl u kome se dogodila greška i liniju u kojoj se dogodila greška. Ovi parametri prosleđuju se respektivno. <script type="text/javascript"> Naravno, funkcija za obradu događaja nije morala da bude anonimus funkcija. Mogli smo jednostavno, deklarisati funkciju i pridružiti je onerror događaju. function mojaFunkcija(){ ..... } Najvažnije iz lekcije
|