Voorbeeld van foutafhandeling: CustomErrors-toepassing

Flash Player 9 of hoger, Adobe AIR 1.0 of hoger

De CustomErrors-toepassing demonstreert technieken voor het werken met aangepaste fouten bij het maken van een toepassing. Deze technieken zijn:

  • Een XML-pakket valideren

  • Een aangepaste fout schrijven

  • Aangepaste fouten genereren

  • De gebruikers laten weten dat een fout is gegenereerd

Zie www.adobe.com/go/learn_programmingAS3samples_flash_nl als u de toepassingsbestanden voor dit voorbeeld wilt downloaden. U vindt de bestanden voor de CustomErrors-toepassing in de map Samples/CustomError. De toepassing bestaat uit de volgende bestanden:

Bestand

Beschrijving

CustomErrors.mxml

of

CustomErrors.fla

Het hoofdtoepassingsbestand in Flash (FLA) of Flex (MXML)

com/example/programmingas3/errors/ApplicationError.as

Een klasse die ook fungeert als basisfoutklasse voor de klassen FatalError en WarningError.

com/example/programmingas3/errors/FatalError.as

Een klasse die een door de toepassing gegenereerde fout van het type FatalError definieert. Deze klasse breidt de aangepaste klasse ApplicationError uit.

com/example/programmingas3/errors/Validator.as

Een klasse die één methode definieert voor de validatie van een door de gebruiker opgegeven employee-XML-pakket.

com/example/programmingas3/errors/WarningError.as

Een klasse die een door de toepassing gegenereerde fout van het type WarningError definieert. Deze klasse breidt de aangepaste klasse ApplicationError uit.

Overzicht CustomErrors-toepassing

Wanneer de toepassing wordt geladen, wordt de methode initApp() aangeroepen voor Flex-toepassingen of wordt de tijdlijncode (niet functioneel) uitgevoerd voor Flash Professional-toepassingen. Deze code definieert een voorbeeld-XML-pakket dat door de klasse Validator wordt gecontroleerd. De volgende code wordt uitgevoerd:

employeeXML =  
    <employee id="12345"> 
        <firstName>John</firstName> 
        <lastName>Doe</lastName> 
        <costCenter>12345</costCenter> 
        <costCenter>67890</costCenter> 
    </employee>; 
}

Het XML-pakket wordt later in het werkgebied weergegeven in een instantie van een TextArea-component. Hierdoor kunt u het XML-pakket wijzigen voordat u probeert het opnieuw te valideren.

Wanneer de gebruiker op de knop Valideren klikt, wordt de methode validateData() aangeroepen. Deze methode valideert het employee-XML-pakket met de methode validateEmployeeXML() uit de klasse Validator. De volgende code toont de methode validateData():

function validateData():void 
{ 
    try 
    { 
        var tempXML:XML = XML(xmlText.text); 
        Validator.validateEmployeeXML(tempXML); 
        status.text = "The XML was successfully validated."; 
    } 
    catch (error:FatalError) 
    { 
        showFatalError(error); 
    } 
    catch (error:WarningError) 
    { 
        showWarningError(error); 
    } 
    catch (error:Error) 
    { 
        showGenericError(error); 
    } 
}

Eerst wordt een tijdelijk XML-object gemaakt met behulp van de inhoud van de instantie xmlText van de TextArea-component. Vervolgens wordt de methode validateEmployeeXML() uit de aangepaste klasse Validator aangeroepen (com.example.programmingas3/errors/Validator.as) en wordt het tijdelijke XML-object doorgegeven als parameter. Als het XML-pakket geldig is, geeft de instantie status van de Label-component een succesbericht weer en wordt de toepassing afgesloten. Als de methode validateEmployeeXML() een aangepaste fout genereert (dat wil zeggen, dat een FatalError, WarningError of een algemene Error optreedt), wordt de desbetreffende instructie catch uitgevoerd die de methodeshowFatalError(), showWarningError() of showGenericError() aanroept. Deze methoden geven elk het toepasselijke bericht weer in een tekstgebied, statusText, om de gebruiker op de hoogte te stellen van de specifieke fout. Elke methode werkt ook de instantie status van de Label-component bij met een specifiek bericht.

Als een fatale fout optreedt tijdens een poging om het employee-XML-pakket te valideren, wordt de foutmelding weergegeven in het tekstgebied statusText en worden de instantie xmlText van de TextArea-component en de instantie validateBtn van de Button-component uitgeschakeld, zoals in de volgende code wordt getoond:

function showFatalError(error:FatalError):void 
{ 
    var message:String = error.message + "\n\n"; 
    var title:String = error.getTitle(); 
    statusText.text = message + " " + title + "\n\nThis application has ended."; 
    this.xmlText.enabled = false; 
    this.validateBtn.enabled = false; 
    hideButtons(); 
}

Als een waarschuwingsfout in plaats van een fatale fout optreedt, wordt de foutmelding weergegeven in de TextArea-instantie statusText, maar in dit geval worden de xmlText-instanties van de TextField- en Button-component niet uitgeschakeld. De methode showWarningError() geeft het aangepaste foutbericht weer in het tekstgebied statusText. In deze melding wordt de gebruiker ook gevraagd of hij of zij wil doorgaan met de XML-validatie of dat het script moet worden geannuleerd. Het volgende fragment toont de methode showWarningError():

function showWarningError(error:WarningError):void 
{ 
    var message:String = error.message + "\n\n" + "Do you want to exit this application?"; 
    showButtons(); 
    var title:String = error.getTitle(); 
    statusText.text = message; 
}

Wanneer de gebruiker op de knop Ja of Nee klikt, wordt de methode closeHandler() aangeroepen. Het volgende fragment toont de methode closeHandler():

function closeHandler(event:CloseEvent):void 
{ 
    switch (event.detail) 
    { 
        case yesButton: 
            showFatalError(new FatalError(9999)); 
            break; 
        case noButton: 
            statusText.text = ""; 
            hideButtons(); 
            break; 
    } 
}

Als de gebruiker ervoor kiest het script te annuleren door op Ja te klikken, wordt een FatalError gegenereerd, waardoor de toepassing wordt afgesloten.

Een aangepaste validator maken

De aangepaste klasse Validator bevat één methode: validateEmployeeXML(). De methode validateEmployeeXML() werkt met één argument (employee). Dit is het XML-pakket dat u wilt valideren. De methode validateEmployeeXML() ziet er als volgt uit:

public static function validateEmployeeXML(employee:XML):void 
{ 
    // checks for the integrity of items in the XML 
    if (employee.costCenter.length() < 1) 
    { 
        throw new FatalError(9000); 
    } 
    if (employee.costCenter.length() > 1) 
    { 
        throw new WarningError(9001); 
    } 
    if (employee.ssn.length() != 1) 
    { 
        throw new FatalError(9002); 
    } 
}

Om te worden gevalideerd moet een employee tot één kostenplaats behoren (absoluut niet meer dan één kostenplaats). Als de employee tot geen enkele kostenplaats behoort, genereert de methode een FatalError, die omhoog loopt naar de methode validateData() in het hoofdtoepassingsbestand. Als de employee tot meer dan één kostenplaats behoort, wordt een WarningError gegenereerd. De definitieve controle in de XML-validator is dat de gebruiker precies één sofinummer heeft gedefinieerd (de node ssn in het XML-pakket). Als er niet precies één node van het type ssn is, wordt een FatalError gegenereerd.

U kunt extra controles aan de methode validateEmployeeXML() toevoegen, bijvoorbeeld om ervoor te zorgen dat de node ssn een geldig nummer bevat of dat voor de werknemer ten minste één telefoonnummer en e-mailadres is gedefinieerd en dat beide waarden geldig zijn. U kunt de XML ook zo aanpassen dat elke employee een unieke id heeft en dat daarbij de id van zijn of haar manager is opgegeven.

De klasse ApplicationError definiëren

De klasse ApplicationError fungeert als basisklasse voor de klassen FatalError en WarningError. De klasse ApplicationError breidt de klasse Error uit en definieert eigen aangepaste methoden en eigenschappen, waaronder een fout-id, de ernst en een XML-object met daarin de aangepaste foutcodes en foutmeldingen. Deze klasse definieert ook twee statische constanten waarmee de ernst van elk fouttype wordt gedefinieerd.

De constructormethode van de klasse ApplicationError ziet er als volgt uit:

public function ApplicationError() 
{ 
    messages =  
        <errors> 
            <error code="9000"> 
                <![CDATA[Employee must be assigned to a cost center.]]> 
            </error> 
            <error code="9001"> 
                <![CDATA[Employee must be assigned to only one cost center.]]> 
            </error> 
            <error code="9002"> 
                <![CDATA[Employee must have one and only one SSN.]]> 
            </error> 
            <error code="9999"> 
                <![CDATA[The application has been stopped.]]> 
            </error> 
        </errors>; 
}

Elke foutnode in het XML-object bevat een unieke numerieke code en een foutmelding. Foutmeldingen kunnen gemakkelijk worden opgezocht aan de hand van hun foutcode in E4X. Dit wordt in de volgende methode getMessageText() getoond:

public function getMessageText(id:int):String 
{ 
    var message:XMLList = messages.error.(@code == id); 
    return message[0].text(); 
}

De methode getMessageText() werkt met één argument van een geheel getal (id) en retourneert een tekenreeks. Het argument id is de foutcode voor de fout die moet worden opgezocht. Wanneer bijvoorbeeld een id van 9001 wordt doorgegeven, komt u bij de foutmelding te weten dat medewerkers maar aan één kostenplaats mogen worden toegewezen. Als er meerdere fouten met dezelfde foutcode zijn, retourneert ActionScript alleen de foutmelding van het eerste gevonden resultaat (message[0] in het geretourneerde XMLList-object).

De volgende methode in deze klasse (getTitle()) heeft geen parameters en retourneert een tekenreekswaarde met daarin de fout-id voor deze specifieke fout. Deze waarde wordt gebruikt om duidelijk te maken welke fout precies is opgetreden tijdens de validatie van het XML-pakket. Het volgende fragment toont de methode getTitle():

public function getTitle():String 
{ 
    return "Error #" + id; 
}

De laatste methode in de klasse ApplicationError is toString(). Deze methode negeert de functie die in de klasse Error is gedefinieerd, waardoor u de presentatie van de foutmelding kunt aanpassen. De methode retourneert een tekenreeks die het specifieke foutnummer en de melding duidelijk maakt.

public override function toString():String 
{ 
    return "[APPLICATION ERROR #" + id + "] " + message; 
}

De klasse FatalError definiëren

De klasse FatalError breidt de aangepaste klasse ApplicationError uit en definieert drie methoden: de constructor FatalError, getTitle() en toString(). De eerste methode, de constructor FatalError, werkt met één argument van een geheel getal (errorID) en bepaalt de ernst van de fout met behulp van de waarden van de statische constanten die in de klasse ApplicationError zijn gedefinieerd. De foutmelding van de specifieke fout wordt opgevraagd door de methode getMessageText() uit de klasse ApplicationError aan te roepen. De constructor FatalError ziet er als volgt uit:

public function FatalError(errorID:int) 
{ 
    id = errorID; 
    severity = ApplicationError.FATAL; 
    message = getMessageText(errorID); 
}

De volgende methode in de klasse FatalError (getTitle()) negeert de methode getTitle() die eerder in de klasse ApplicationError is gedefinieerd en voegt de tekst ‘-- FATAL’ toe aan de titel om de gebruiker duidelijk te maken dat een fatale fout is opgetreden. De methode getTitle() ziet er als volgt uit:

public override function getTitle():String 
{ 
    return "Error #" + id + " -- FATAL"; 
}

De laatste methode in deze klasse (toString()) negeert de methode toString() die in de klasse ApplicationError is gedefinieerd. De methode toString() ziet er als volgt uit:

public override function toString():String 
{ 
    return "[FATAL ERROR #" + id + "] " + message; 
}

De klasse WarningError definiëren

De klasse WarningError breidt de klasse ApplicationError uit en is vrijwel identiek aan de klasse FatalError op een paar kleine wijzigingen in de tekenreeksen na. Hiermee wordt de ernst van de fout op ApplicationError.WARNING in plaats van ApplicationError.FATAL gezet, zoals in de volgende code wordt getoond:

public function WarningError(errorID:int) 
{ 
    id = errorID; 
    severity = ApplicationError.WARNING; 
    message = super.getMessageText(errorID); 
}