Szerver oldalon olyan kényelmes (IntelliSense) String.IsNullOrEmpty-t hívni, as-zel kasztolni és nullt vizsgálni, vagy éppen ArgumentNullExceptiont dobni, amikor egy metódus bemeneti paramétereit akarjuk ellenőrizni. Kliens oldalon, javascriptben egészen más a helyzet: minden leütött karakter és begépelt kódsor fáj, hiszen számtalan hibalehetőséget rejt magában.
A példa kedvéért vegyünk egy igazán egyszerű javascript metódust, amiben négyezetre akarjuk emelni a bemeneti paraméter értékét:
function square( i )
{
if( i === undefined )
alert( "Meg kell adni a négyzetre emelendő számot!" );
if( typeof( i ) !== 'number' )
alert( "Csak számot lehet négyzetre emelni!" );
if( isNaN( i ) )
alert( "A megadott paraméternek számnak kell lennie!" );
return i * i;
}
Felugráló hibaüzenet hegyek, elég csak paraméter nélkül meghívni ezt a metódust. Ha ezt a mintát követjük, a hibakereséshez az egyetlen rendelkezésünkre álló információ a hibaüzenet. Na de melyik programozó ír ki értelmes hibaüzenetet önként és dalolva? ;-) Főleg miután ennyi kódot volt kénytelen írni, hiszen ne felejtsük el, nem erősen típusos környezetben vagyunk!
Kicsit javíthatunk a helyezeten, ha használjuk a Microsoft AJAX Library-t, az ugyanis kiterjeszti az Error osztályt úgy, hogy kivételeket hajigálhassunk vele:
function square( i )
{
if( i === undefined )
throw Error.argumentUndefined( "i", "Meg kell adni a négyzetre emelendő számot!" );
if( typeof( i ) !== 'number' )
throw Error.argumentType( "i", Object.getType( i ), Number, 'Csak számot lehet négyzetre emelni!' );
if( isNaN( i ) )
throw Error.argumentNull( "i", "A megadott paraméternek számnak kell lennie!" );
return i * i;
}
Akit érdekel, hogy érték ezt el Redmondban, bátran nézzen bele a MicrosoftAjax.debug.js fájlba, az Error osztály a 223. sor körül kezdődik. Ezeket a kivétel típusokat lehet megtalálni:
- Sys.ArgumentException
- Sys.ArgumentNullException
- Sys.ArgumentOutOfRangeException
- Sys.ArgumentTypeException
- Sys.ArgumentUndefinedException
- Sys.InvalidOperationException
- Sys.NotImplementedException
- Sys.ParameterCountException
- Sys.ScriptLoadFailedException
Aki nem fél dokumentálatlan vizekre evezni, ennél átláthatóbb kódot is írhat. A Microsoft AJAX Library fájljait nézegetve feltűnhet egy Function._validateParams metódus, amivel a szinte minden metódus ellenőrzi a bemenő paramétereit. Nosza, használjuk fel, immár egy bonyolultabb példán, aminek több paramétere van:
function square2( x, showResult, msg )
{
var e = Function._validateParams( arguments, [
{ name: "x", type: Number, integer: true },
{ name: "showResult", type: Boolean },
{ name: "msg", type: String, optional: true }
] );
if( e )
throw e;
if( msg !== undefined )
var result = String.format( msg, x * x );
else
var result = String.format( "Az eredmény: {0} * {0} = {1}", x, x * x );
if( showResult )
alert( result );
return result;
}
A _validateParams metódusnak JSON formában adhatjuk át, hogy mit és hogyan szeretnénk ellenőrizni. Már-már deklaratív leírásnak is tekinthetjük. A következő lehetőségeink vannak:
- name: a paraméter neve.
- type: a paraméter típusa, String, Number, Boolean, Array vagy bármilyen saját típus.
- mayBeNull: a paraméter értéke lehet-e null, az alapértelmezett false.
- optional: elhagyható-e a paraméter, az alapértelmezett false.
- parameterArray: a paraméter tömb, az alapértelmezett false.
- integer: a paraméter egész szám, az alapértelmezett false.
- elementType: ha a paraméter tömb, akkor a tömb elemeinek típusa.
- elementInteger: ha a paraméter tömb, akkor ellenőrzi, hogy minden elem egész szám legyen.
- elementDomElement: ha a paraméter tömb, akkor ellenőrzi, hogy minden eleme DOM elem legyen.
- elementMayBeNull: ha a paraméter tömb, akkor ellenőrzi, hogy lehet-e null eleme vagy sem.
Nincs is más dolgunk, mint a metódus által visszaadott kivételt (a fenti példában e) jó messzi eldobni, erre szolgál a throw e.
Már csak egy kérdés maradt: hogyan kezeli a hívó a kivételt? Természetesen try-catch blokkal, majdnem ugyanúgy, mint szerver oldalon, például így:
try
{
square2(); // Hibás, mert nincs paramétere
}
catch( e )
{
if( e.name === "Sys.ParameterCountException" )
alert( "Nem jó: " + e.message );
}
Itt is erősen típusos érzetünk lehet, a name tulajdonságból kiderül a kivétel típusa, a message pedig a szöveget tartalmazza. Bár a Microsoft AJAX Library támogatja a lokalizációt, a hibaüzenet alapértelmezett szövege sajnos nem lokalizálható, az ugyanis a Sys.Res osztálytól kap értéket :( Ezt az osztályt szintén a MicrosoftAjax.debug.js fájlban találjuk, éppen a legvégén, az összes üzenet ott található sztringként, ha nagyon akarjuk, átírhatjuk.
A _validateParams metódus nagy áldás egy nem típusos környezetben. Remélem a Visual Studio 2008-ban remek IntelliSense is lesz már hozzá, de azt se bánnám, ha szerver oldalon is lehetne attribútumokat így használni.