Gestion des erreurs synchrones dans une application

Flash Player 9 et les versions ultérieures, Adobe AIR 1.0 et les versions ultérieures

La gestion des erreurs la plus courante est la logique de gestion des erreurs synchrones, qui consiste à insérer des instructions dans votre code pour intercepter les erreurs synchrones lors de l’exécution d’une application. Ce type de gestion des erreurs permet à votre application de repérer des erreurs d’exécution et de les résoudre lorsque des fonctions échouent. La logique d’interception d’une erreur synchrone fait appel aux instructions try..catch..finally, qui tentent littéralement une opération, interceptent toute réponse à l’erreur émanant du moteur d’exécution Flash, puis exécutent une autre opération pour gérer l’opération qui a échoué.

Utilisation des instructions try..catch..finally

Lorsque vous manipulez des erreurs d’exécution synchrones, utilisez les instructions try..catch..finally pour intercepter les erreurs. Lorsqu’une erreur d’exécution se produit, le moteur d’exécution Flash renvoie une exception, ce qui signifie qu’il suspend l’exécution normale et crée un objet spécial de type Error. L’objet Error est ensuite renvoyé au premier bloc catch disponible.

L’instruction try regroupe les instructions pouvant créer des erreurs. Vous utilisez toujours l’instruction catch avec une instruction try. Si une erreur est détectée dans l’une des instructions du bloc try, les instructions catch associées à cette instruction try sont exécutées.

L’instruction finally regroupe les instructions exécutées, qu’une erreur se produise ou non dans le bloc try. S’il ne se produit pas d’erreur, les instructions du bloc finally sont exécutées au terme de l’exécution des instructions du bloc try. S’il se produit une erreur, l’instruction catch appropriée est exécutée en premier lieu, suivie des instructions du bloc finally.

Le code suivant illustre la syntaxe d’utilisation des instructions try..catch..finally :

try 
{ 
    // some code that could throw an error 
} 
catch (err:Error) 
{ 
    // code to react to the error 
} 
finally 
{ 
    // Code that runs whether an error was thrown. This code can clean 
    // up after the error, or take steps to keep the application running. 
}

Chaque instruction catch identifie un type d’exception spécifique qu’elle gère. L’instruction catch peut spécifier uniquement des classes d’erreur qui sont des sous-classes de la classe Error. Chaque instruction catch est vérifiée dans l’ordre. Seule la première instruction catch qui correspond au type d’erreur renvoyé est exécutée. En d’autres termes, si vous vérifiez d’abord la classe Error de niveau supérieur, puis une sous-classe de la classe Error, seule la classe Error de niveau supérieur est prise en compte. Le code suivant illustre ce point :

try 
{ 
    throw new ArgumentError("I am an ArgumentError"); 
} 
catch (error:Error) 
{ 
    trace("<Error> " + error.message); 
} 
catch (error:ArgumentError) 
{ 
    trace("<ArgumentError> " + error.message); 
}

Le code précédent affiche le résultat suivant :

<Error> I am an ArgumentError

Pour intercepter correctement l’erreur ArgumentError, assurez-vous que les types d’erreur les plus spécifiques sont répertoriés en premier, suivis des types d’erreur plus génériques, comme l’indique le code suivant :

try 
{ 
    throw new ArgumentError("I am an ArgumentError"); 
} 
catch (error:ArgumentError) 
{ 
    trace("<ArgumentError> " + error.message); 
} 
catch (error:Error) 
{ 
    trace("<Error> " + error.message); 
}

Plusieurs méthodes et propriétés de l’API d’ActionScript renvoient des erreurs d’exécution si elles en rencontrent lors de leur exécution. Par exemple, la méthode close() de la classe Sound renvoie une erreur IOError si la méthode ne parvient pas à fermer le flux audio, comme indiqué dans le code suivant :

var mySound:Sound = new Sound(); 
try 
{ 
    mySound.close(); 
} 
catch (error:IOError) 
{ 
    // Error #2029: This URLStream object does not have an open stream. 
}

Au fur et à mesure que vous vous familiariserez avec le manuel Guide de référence ActionScript 3.0 pour la plate-forme Adobe Flash, vous identifierez les méthodes qui renvoient des exceptions, comme indiqué dans la description de chaque méthode.

Instruction throw

Les moteurs d’exécution Flash renvoient des exceptions s’ils rencontrent des erreurs lors de l’exécution de votre application. En outre, vous pouvez renvoyer des exceptions de façon explicite à l’aide de l’instruction throw. Si tel est le cas, Adobe vous conseille de renvoyer des occurrences de la classe Error ou de ses sous-classes. Le code suivant illustre une instruction throw qui renvoie une occurrence de la classe Error, MyErr, et appelle une fonction, myFunction() en réponse au renvoi de l’erreur :

var MyError:Error = new Error("Encountered an error with the numUsers value", 99); 
var numUsers:uint = 0; 
try 
{ 
    if (numUsers == 0) 
    { 
        trace("numUsers equals 0"); 
    } 
} 
catch (error:uint) 
{ 
    throw MyError; // Catch unsigned integer errors. 
} 
catch (error:int) 
{ 
    throw MyError; // Catch integer errors. 
} 
catch (error:Number) 
{ 
    throw MyError; // Catch number errors. 
} 
catch (error:*) 
{ 
    throw MyError; // Catch any other error. 
} 
finally  
{ 
    myFunction(); // Perform any necessary cleanup here. 
}

Les instructions catch sont classées de façon à ce que les types de données les plus spécifiques apparaissent en premier. Si l’instruction catch associée au type de données Number est répertoriée en premier, ni l’instruction catch associée au type de données uint, ni l’instruction catch associée au type de données int n’est exécutée.

Remarque : dans le langage de programmation Java, chaque fonction qui peut renvoyer une exception doit le déclarer en répertoriant les classes d’exception qu’elle peut renvoyer dans une clause throws associée à la déclaration de la fonction. ActionScript ne requiert pas que vous déclariez les exceptions renvoyées par une fonction.

Affichage d’un message d’erreur simple

L’un des avantages majeurs du nouveau modèle d’événement d’erreur et d’exception consiste à permettre d’informer les utilisateurs du moment où une action échoue et de la raison de cet échec. Votre rôle consiste à écrire le code pour afficher le message et à offrir des options en réponse.

Le code suivant illustre une instruction try..catch simple permettant d’afficher l’erreur dans un champ de texte :

package 
{ 
    import flash.display.Sprite; 
    import flash.text.TextField; 
     
    public class SimpleError extends Sprite 
    { 
        public var employee:XML =  
            <EmpCode> 
                <costCenter>1234</costCenter> 
                <costCenter>1-234</costCenter> 
            </EmpCode>; 
 
        public function SimpleError() 
        { 
            try 
            { 
                if (employee.costCenter.length() != 1) 
                { 
                    throw new Error("Error, employee must have exactly one cost center assigned."); 
                } 
            }  
            catch (error:Error) 
            { 
                var errorMessage:TextField = new TextField(); 
                errorMessage.autoSize = TextFieldAutoSize.LEFT; 
                errorMessage.textColor = 0xFF0000; 
                errorMessage.text = error.message; 
                addChild(errorMessage); 
            } 
        } 
    } 
}

En utilisant un plus grand nombre de classes d’erreur et d’erreurs de compilateur intégrées, ActionScript 3.0 fournit de plus amples informations sur les raisons de l’échec d’une action que les versions précédentes. Ces informations permettent de créer des applications plus stables qui gèrent mieux les erreurs.

Renvoi des erreurs

Lorsque vous créez une application, vous êtes parfois amené à renvoyer une erreur si vous ne parvenez pas à la gérer correctement. Par exemple, le code suivant illustre un bloc try..catch imbriqué, qui renvoie une erreur ApplicationError personnalisée si le bloc catch imbriqué n’est pas capable de gérer l’erreur :

try 
{ 
    try 
    { 
        trace("<< try >>"); 
        throw new ApplicationError("some error which will be rethrown"); 
    } 
    catch (error:ApplicationError) 
    { 
        trace("<< catch >> " + error); 
        trace("<< throw >>"); 
        throw error; 
    } 
    catch (error:Error) 
    { 
        trace("<< Error >> " + error); 
    } 
} 
catch (error:ApplicationError) 
{ 
    trace("<< catch >> " + error); 
}

Le résultat issu du fragment de code précédent serait le suivant :

<< try >> 
<< catch >> ApplicationError: some error which will be rethrown 
<< throw >> 
<< catch >> ApplicationError: some error which will be rethrown

Le bloc try imbriqué renvoie une erreur ApplicationError personnalisée qui est interceptée par le bloc catch suivant. Ce bloc catch imbriqué peut tenter de gérer l’erreur et, si la tentative échoue, renvoyer l’objet ApplicationError au bloc try..catch.