A Java irányvonal mentén haladva szintén try–catch–finally lehetőséget nyújt nekünk az ActionScript. Egy catch ágra akkor kerül a vezérlés, ha az eldobott objektum az ág belépési típusának a leszármazottja. Egyébként bármilyen objektumot el lehet dobni a throw utasítással, de ajánlott az Error osztályból származtatni a kivételeinket, ami saját kivételeink jelzésére is alkalmas. A Flash-re jellemző, hogy még nem igazán használja ki a kivételkezelést, gyakran alkalmaz inkább callback hibakezelő függvényeket. A finally blokk mindenképpen végrehajtódik, ha történt kivétel, ha nem. Még akkor is, ha a try blokkban return utasítással kilépünk. A try blokkot mindig követnie kell egy catch vagy egy finally blokknak, vagy mindkettőnek. Egy try blokkhoz több catch is tartozhat, ez akkor lehet, ha a catch ágak paraméterei (a kivételek típusai) különbözőek, viszont csak egy finally kapcsolódhat hozzá. Tetszőleges számú try blokk egymásba skatulyázható. A catch kezelőben használhatunk típusos változókat.
class Circle { private var x:Number, y:Number; private var r:Number; function Circle(x:Number, y:Number, r:Number) { this.x = x; this.y = y; if ( r <= 0 ) { throw Error("Negative radius") } this.r = r; } } try { var c:Circle = new Circle(100, 100, -10); } catch(e:Error) { trace(e.toString()); } finally { delete c; }
Az Error osztálynak van egy toString() tagfüggvénye, ami visszaadja az Error objektum által reprezentált stringet. Tartalmaz két adattagot: message (hibaüzenet) és name (az error objektum neve). Egy új Error objektum létrehozása: new Error([message:String]) : Error. Így létrejön egy új Error objektum, és ha a message paraméter nem volt üres, akkor ezt kapja értékül az Error.message adattag. Kivétel dobásakor, vagyis akkor, amikor a try ágban valami hiba lép fel, az ágban lévő további utasítások nem hajtódnak végre, a vezérlés rögtön az catch ágra ugrik.
Régebbi AS verziókban a hibák egyszerűen rejtve maradhattak, mivel a player többnyire "lenyelte" őket és nem értesített a bekövetkeztükről. Ha megpróbáltunk egy nem létező változóra hivatkozni, általában csak az értékéből következtethettünk arra, hogy elírtunk valamit, vagy rossz helyre hivatkoztunk. Ez komplikáltabb kódok esetén hosszas hibakeresést eredményezett és sok fejtörést. Ennek mostantól vége, a fejlesztőkörnyezet és a Debug Flash Player minden hibáról értesít minket és arra is rámutat, hogy hol keletkeztek. A régi hibákkal ellentétben nem tudjuk megúszni a hibakezelést, ugyanis szinkron hibák esetén előfordulhat, hogy az utána következő kód nem fut le, így fontos, hogy ezekre felkészüljünk.
Ezek azok a hibák, amelyek futás közben keletkeznek, valamelyik kód-részlet végrehajtása közben. Lehet az egy rossz típus-konverzió, vagy ha például egy null objektumon próbálunk változókat elérni. Az ilyen hibák keletkezésekor a player abbahagyja a kód futtatását és az Error osztály egy példányát dobja, amit lehetőség van elkapni és lekezelni a try..catch..finally blokk segítségével (hibakezelés). Próbáljunk meg elérni egy változót egy null objektumon:
var obj:Object obj.x TypeError: Error #1009: Cannot access a property or method of a null object reference. at Untitled_fla::MainTimeline/Untitled_fla::frame1()
A fenti hibához hasonlót kell kapnunk, ami egy TypeError, vagyis a TypeError osztály egy példánya. Természetesen ez a hiba is az Error osztályból származik. Próbáljuk meg elkapni a hibát:
var obj:Object try{ obj.x }catch(error:Error){ trace("hiba") } Eredmény: -------------------------- hiba --------------------------
Most, hogy mi kezeltük le a hibát, akármit kiírhatunk helyette és a kódunk is tovább futhat ha úgy akarjuk (lekezelés). A try blokk elkap minden keletkező hibát és továbbküldi azt a catch-nek, ahol -ha a hiba a megfelelő típusú-, lefut a megfelelő catch blokk. Mivel a mi hibánk TypeError ezért az Error típusú paraméterrel azt is elkaphatjuk. Lehetőség van többféle típusú hiba figyelésére is több catch blokk létrehozásával, azonban mindig haladjunk a legspecifikusabb hibától a legáltalánosabbig.
var obj:Object try{ obj.x }catch(error:TypeError){ trace("TypeError") }catch(error:Error){ trace("Error") } Eredmény: -------------------------- TypeError --------------------------
Lehetőség van a try..catch részt kiegészíteni egy finally blokkal, ami mindenképpen lefut, ha történt hiba, ha nem.
var obj:Object; var errorHappened:Boolean try { obj.x; } catch (error:Error) { errorHappened = true }finally{ if(errorHappened){ trace("Hiba történt") }else{ trace("Nem volt hiba") } } Eredmény: -------------------------- Hiba történt --------------------------
Az Error osztály számos tulajdonsággal rendelkezik, amik segítségével lekérhetjük a hiba szövegét, vagy a hiba típusát. Írassunk ki párat erek közül:
var obj:Object; try { obj.x; } catch (error:Error) { trace("Hiba ID: ",error.errorID) trace("Hiba üzenet: ",error.message) trace("Hiba neve: ",error.name) } Eredmény: -------------------------- Hiba ID: 1009 Hiba üzenet: Error #1009: Cannot access a property or method of a null object reference. Hiba neve: TypeError --------------------------
Természetesen a try blokkban több sornyi kódot is elhelyezhetünk, azonban a hiba keletkezése utáni részek már nem fognak lefutni, hanem ugrik a kód a catch részhez.
var obj:Object; try { obj.x; trace("Hello") } catch (error:Error) { trace("Hiba") } Eredmény: -------------------------- Hiba --------------------------
Ezek azok a hibák, amelyek aszinkron műveletek végrehajtása közben keletkeznek. Ilyen lehet például a fájlok betöltése. Ezeket a hibákat nem tudjuk a fent bemutatott módszerrel lekezelni, mert mikor bekövetkeznek a kódunk már tovább futott. Aszinkron hibák jelzésére eseményeket generál a player, amiket figyelőkkel el tudunk kapni. Ezeknek az eseményeknek az alapja az ErrorEvent osztály ami szintén alosztálya az Event-nek. Próbáljunk meg betölteni egy nem létező fájlt:
var loader:Loader = new Loader(); loader.load(new URLRequest("c:/none.swf")); Error #2044: Unhandled IOErrorEvent:. text=Error #2035: URL Not Found.
Hasonló hibát kell kapnunk, ami arról tájékoztat, hogy egy lekezeletlen IOErrorEvent típusú esemény keletkezett. Ha figyelőket adunk ehhez az eseményhez, már megszűnik ez a figyelmeztetés. A loader esetén -ahogy arról már fentebb is szó volt- a contentLoaderInfo-hoz kell ilyen figyelőket hozzáadnunk.
var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onError) loader.load(new URLRequest("c:/none")); function onError(event:ErrorEvent):void{ trace("Hiba Történt") trace("Hiba szövege: "+event.text) } Eredmény: -------------------------- Hiba Történt Hiba szövege: Error #2035: URL Not Found. URL: file:///c:/none --------------------------
Minden osztálynál a súgóban fel vannak sorolva azok az események, amelyeket küldeni tud, melyek között a hibakezelő események is szerepelnek.