Vynimky v Javascripte

Vynimky v Javascripte

12. 12. 2013

Vynimka je reakcia na vynimocnu situaciu vzniknutu za behu programu.

Zachytenie a spracovanie vynimky

Syntax

try {
    try_prikazy
}
[catch (vynimka) {
    catch_prikazy
}]
[finally {
    finally_prikazy
}]

Obsluha vynimky pozostava z bloku try obsahujuci prikazy a aspon jedneho catch alebo finally bloku. To znamena, ze existuju 3 formy:

  1. try...catch
  2. try...finally
  3. try...catch...finally

try...catch

Blok catch obsahuje prikazy, ktore urcuju, co robit ak je vyvolana vynimka v bloku try. Ak nejaky prikaz (alebo vyvolana funkcia) v bloku try vyvola vynimku, okamzite sa prepne do klauzuly catch. Ak nieje vyvolana ziadna vynimka, klauzula catch je preskocena.

try {
    throw "myException"; // generuje vynimku
}
catch (e) {
   // prikazy, ktore spracuju akukolvek vynimku
}

finally

finally blok je vzdy v try...catch ako posledny. Je vykonany vzdy, bez ohladu na to, ci bola vynimka vyvolana alebo chytena. Tento blok je urceny pre 'zaverecne upratovanie'.

openMyFile()
try {
    writeMyFile(theData);
}
finally {
    closeMyFile(); // pokazde zavrie subor
}

Vnorenie vynimky

Jednou z moznosti je vnorenie try blokov.

Ak vynimka nastane v ramci vnutorneho try-catch a blok try nema zodpovedajuci catch, po vykonani bloku finally, spracuje vynimku vonkajsi try-catch.

Nechat spracovanie vynimky na vyssej urovni je len na vas a moze mat svoje vyuzitie. Jednym zo scenarov moze byt, ze mate len try-finally bez bloku catch, a vonkajsi try-catch spracuje loggovanie chyb.

Standardne vynimky

Javascript disponuje siestimi Error triedami, ktore rozsiruju objekt Error.

EvalError:
Chyba spojena s funkciou eval().

RangeError:
Cislo nespada do pozadovaneho rozsahu.

ReferenceError:
Je odkazane na neexistujucu premennu.

SyntaxError:
Pokus o interpretaciu neplatneho kodu.

TypeError:
Premenna alebo parameter je neplatneho typu.

URIError:
Podana neplatna URI.

Vyvolanie vynimky

Vynimku vyvolame prikazom throw, po ktorom nasleduje cislo, retazec, bool, objekt, ...

Jednou z moznosti je vyvolat Error, a ako parameter mu dat zrozumitelny popis chyby:

throw new TypeError("Parameter vek musi byt cislo."); 

Dalsou je vyvolat objekt:

throw { 
    name:    "Systemova chyba", 
    message: "Vyskytla sa chyba. Prosim kontaktujte administratora."
}

Alebo vytvorit vlastnu triedu a vyvolat rovnako ako standardny Error:

function MyException(message) {
    this.message = message;
    this.name = "MyException";
}

throw new MyException("Telefon nieje spravneho formatu."); 

Spracovanie viacerych typov vynimiek

V bloku try mozete odchytit viacero typov vynimiek. Preto by bolo pekne, ak by sme mohli spracovat konkretnu vynimku, na zaklade typu. V nasledujucich prikladoch mozete vidiet ako v bloku catch otestujeme jednotlivy typ pre nasledne spracovanie.

Na MDN najdete elegantny sposob, zial ten nepodporuju vsetky prehliadace:

try {
    myFunction(); // moze vyvolat vynimku
} catch (e if e instanceof TypeError) {
    // TypeError
} catch (e if e instanceof RangeError) {
    // RangeError
} catch (e if e instanceof EvalError) {
    // EvalError
} catch (e) {
    // nespecifikovana vynimka
}

Preto sa musite uspokojit s menej elegatnym sposobom:

try {
    myFunction(); // moze vyvolat vynimku
} catch (e) {
    if(e instanceof TypeError) {
        // TypeError
    } else if (e instanceof RangeError) {
        // RangeError
    } else if (e instanceof EvalError) {
        // EvalError
    } else {
        // nespecifikovana vynimka
    }
}

Rovnaky efekt docielite pomocou switch:

try {
    myFunction(); // moze vyvolat vynimku
} catch (e) {
    switch (true) {
        case (e instanceof TypeError):
            // TypeError
            break;
        case (e instanceof RangeError):
            // RangeError
            break;
        case (e instanceof EvalError):
            // EvalError
            break;
        case default:
            // nespecifikovana vynimka
            break;
    }
}

Rethrow

Po tom, co odchytite vynimku, pouzitim prikazu throw ju mozete znovu vyvolat, ta sa presunie na vyssiu uroven.

try {
    throw n; // vyvolanie vynimky
} catch (e) {
    if (podmienka) {
        // spracovanie znamej vynimky
    } else {
        // nedokaze spracovat vynimku
        throw e; // rethrow
    }
}
comments powered by Disqus