Esempio di gestione degli errori: applicazione CustomErrors

Flash Player 9 e versioni successive, Adobe AIR 1.0 e versioni successive

L'applicazione CustomErrors illustra le tecniche di gestione degli errori personalizzati durante la creazione di un'applicazione. Queste tecniche sono:

  • Convalida di un pacchetto XML

  • Scrittura di un errore personalizzato

  • Generazione di errori personalizzati

  • Notifica agli utenti di ogni errore generato

Per ottenere i file dell'applicazione per questo esempio, visitate la pagina www.adobe.com/go/learn_programmingAS3samples_flash_it. I file dell'applicazione CustomErrors si trovano nella cartella Samples/CustomError. L'applicazione è composta dai seguenti file:

File

Descrizione

CustomErrors.mxml

o

CustomErrors.fla

Il file principale dell'applicazione in Flash (FLA) o Flex (MXML)

com/example/programmingas3/errors/ApplicationError.as

Classe Error che funge da classe base per le classi FatalError e WarningError.

com/example/programmingas3/errors/FatalError.as

Classe che definisce un errore FatalError generato dall'applicazione. Si tratta di un'estensione della classe personalizzata ApplicationError.

com/example/programmingas3/errors/Validator.as

Classe che definisce il metodo di convalida del pacchetto XML dipendente fornito dall'utente.

com/example/programmingas3/errors/WarningError.as

Classe che definisce l'errore WarningError generato dall'applicazione. Si tratta di un'estensione della classe personalizzata ApplicationError.

Panoramica dell'applicazione CustomErrors

Quando l'applicazione viene caricata, il metodo initApp() viene chiamato per le applicazioni Flex o il codice linea temporale (non funzione) viene eseguito per applicazioni Flash Professional. Questo codice definisce un pacchetto XML campione da verificare tramite la classe Validator. Viene eseguito il codice seguente:

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

Il pacchetto XML viene in seguito visualizzato nell'istanza di un componente TextArea sullo stage. Questo passaggio consente di modificare il pacchetto XML prima di sottoporlo a una seconda convalida.

La selezione del pulsante Validate da parte dell'utente chiama il metodo validateData(). Il metodo convalida il pacchetto XML del dipendente tramite il metodo validateEmployeeXML() della classe Validator. Il codice seguente illustra il metodo 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); 
    } 
}

Per cominciare, viene creato un oggetto XML temporaneo usando il contenuto dell'istanza xmlText del componente TextArea. In seguito, viene chiamato il metodo validateEmployeeXML() della classe personalizzata Validator (com.example.programmingas3/errors/Validator.as) che passa l'oggetto XML temporaneo come parametro. Se il pacchetto XML è valido, l'istanza status del componente Label visualizza un messaggio indicante che l'operazione ha avuto esito positivo e l'applicazione si chiude. Se il metodo validateEmployeeXML() genera un errore personalizzato (cioè, se si verifica un errore FatalError, WarningError o GenericError), viene eseguita l'istruzione catch appropriata che chiama il metodo showFatalError(), showWarningError() oppure showGenericError(). Ogni metodo visualizza un messaggio appropriato in un'area di testo denominata statusTex per segnalare all'utente l'errore specifico che si è verificato. Ogni metodo aggiorna, inoltre, l'istanza status del componente Label con un messaggio appropriato.

Se si verifica un errore irreversibile durante il tentativo di convalidare il pacchetto XML del dipendente, il messaggio di errore viene visualizzato nell'area di testo statusText e l'istanza xmlText del componente TextArea e l'istanza validateBtn del componente Button vengono disabilitate, come illustra il codice seguente:

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(); 
}

Se si verifica un'avvertenza in luogo di un errore irrecuperabile, il messaggio di errore viene comunque visualizzato nell'istanza statusText del componente TextArea, ma le istanze dei componenti xmlText e Button non vengono disabilitate. Il metodo showWarningError() visualizza il messaggio di errore personalizzato nell'area di testo statusText. Il messaggio chiede, inoltre, all'utente di decidere se desidera procedere con la convalida del pacchetto XML o annullare lo script. La seguente porzione di codice illustra il metodo 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; 
}

Quando l'utente fa clic sul pulsante Sì o No, viene chiamato il metodo closeHandler(). La seguente porzione di codice illustra il metodo closeHandler():

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

Se l'utente sceglie di annullare lo script facendo clic su Sì, viene generato un errore FatalError e l'applicazione viene interrotta.

Creazione di una classe Validator personalizzata

La classe Validator personalizzata contiene un unico metodo: validateEmployeeXML(). Il metodo validateEmployeeXML() accetta un solo argomento, employee, vale a dire il pacchetto XML da convalidare. Il metodo validateEmployeeXML() è il seguente:

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); 
    } 
}

Per poter essere convalidato, un dipendente deve appartenere a un centro costi (e solo a uno). Se il dipendente non appartiene ad alcun centro costi, il metodo genera un FatalError che si propaga al metodo validateData() nel file principale dell'applicazione. Se il dipendente appartiene a più di un centro costi, viene generato un WarningError. La verifica finale effettuata sul pacchetto XML controlla che per l'utente sia definito un numero di iscrizione alla previdenza sociale (il nodo ssn del pacchetto XML). Se non è disponibile esattamente un nodo ssn, viene generato un FatalError.

Potete aggiungere verifiche supplementari al metodo validateEmployeeXML(), ad esempio, per controllare che il nodo ssn contenga un numero valido o che per il dipendente siano stati definiti almeno un numero di telefono e un indirizzo e-mail e che entrambi i valori siano validi. Si può inoltre modificare il codice XML in modo che ogni dipendente disponga di un ID univoco e indichi l'ID del proprio manager.

Definizione della classe ApplicationError

La classe ApplicationError funge da classe base per le classi FatalError e WarningError. La classe ApplicationError è un'estensione della classe Error che definisce metodi e proprietà specifici, compresa la definizione di un ID errore, la gravità e l'oggetto XML che contiene i codici e i messaggi dell'errore personalizzato. La classe definisce anche due costanti statiche utilizzate per definire la gravità di ogni tipo di errore.

Il metodo costruttore della classe ApplicationError è il seguente:

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>; 
}

Ogni nodo errore dell'oggetto XML contiene un codice numerico e un messaggio univoco. I messaggi di errore possono essere facilmente consultati in base al codice di errore usando E4X, come illustrato nel metodo getMessageText() seguente:

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

Il metodo getMessageText() accetta un solo argomento costituito da un intero, id, e restituisce una stringa. L'argomento id è il codice dell'errore da cercare. Ad esempio, passando un id 9001 si recupera l'errore secondo il quale i dipendenti devono essere assegnati a un solo centro costi. Se più errori condividono lo stesso codice, ActionScript restituisce il messaggio di errore per il primo risultato trovato (message[0] nell'oggetto XMLList restituito).

Il metodo seguente di questa classe, getTitle(), non accetta parametri e restituisce una stringa che contiene l'ID specifico dell'errore. Questo valore viene utilizzato per contribuire all'identificazione dell'errore esatto verificatosi durante la convalida del pacchetto XML. La seguente porzione di codice illustra il metodo getTitle():

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

L'ultimo metodo della classe ApplicationError è toString() che sostituisce la funzione definita nella classe Error per rendere possibile la personalizzazione della presentazione del messaggio di errore. Il metodo restituisce una stringa che identifica un numero di errore specifico e il messaggio.

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

Definizione della classe FatalError

La classe FatalError estende la classe ApplicationError personalizzata e definisce tre metodi: la funzione di costruzione FatalError, il metodo getTitle() e il metodo toString(). Il primo metodo, la funzione di costruzione FatalError, accetta un solo argomento costituito da un numero intero, errorID, imposta la gravità dell'errore mediante valori costanti statici definiti nella classe ApplicationError e ottiene il messaggio di errore specifico chiamando il metodo getMessageText() della classe ApplicationError. La funzione di costruzione FatalError è la seguente:

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

Il metodo seguente della classe FatalError, getTitle(), sostituisce il metodo getTitle() definito nella classe ApplicationError e aggiunge la stringa “-- FATAL” al titolo per informare l'utente che si è verificato un errore irrecuperabile. Il metodo getTitle() è il seguente:

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

L'ultimo metodo di questa classe, toString(), sostituisce il metodo toString() definito nella classe ApplicationError. Il metodo toString() è il seguente:

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

Definizione della classe WarningError

La classe WarningError è un'estensione della classe ApplicationError ed è quasi identica alla classe FatalError, fatta eccezione per un paio di variazioni minime alle stringhe e per il fatto che imposta la gravità dell'errore su ApplicationError.WARNING in luogo di ApplicationError.FATAL, come illustrato nel codice seguente:

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