# Introduction au Lua/Erreurs

Après avoir abordé la structure particulière des modules Scribunto pour Mediawiki, nous avons ensuite étudié quelques caractéristiques élémentaires du langage Lua (ses variables, ses expressions) d'autres caractéristiques fondamentales comme les conditions, les boucles ou encore les fonctions. Nous avons vu ensuite comment la manipulation des tables avec Lua est à la fois essentielle et particulière. Cette nouvelle leçon montre comment gérer les erreurs et exceptions au sein d'un script en cours d’exécution.

## Prérequis

Cette leçon suppose que vous ayez assimilé la leçon Tables.

## Créer un script Lua avec un système de gestion des exceptions

* Accéder au Module:Sandbox.
* Supprimer le code existant.
* Ajouter le code suivant et enregistrer la page:

## Tester votre nouveau script

* Rendez-vous sur "votre page de test".
* Ajouter le code suivant et enregistrer la page:
Le résultat doit correspondre à ceci:

## Comprendre le nouveau script
### Comprendre la fonction reciprocal1

* local function reciprocal1(value) déclare une fonction locale nommée reciprocal1 qui accepte un unique paramètre value, qui est la valeur dont l'inverse sera retourné.
* return 1 / value retourne l'inverse de la valeur.
* end termine la fonction.

### Comprendre la fonction test1

* function p.test1(frame) déclare une fonction locale nommée test1 qui accepte un unique paramètre frame, qui est l'objet utile pour accéder aux paramètres passés par #invoke.
* local value = frame.args[1] définit une variable locale nommée value et lui assigne la valeur du premier argument (paramètre) de l’objet "frame" passé par #invoke.
* return reciprocal1(value) appel la fonction reciprocal1, en lui passant la variable value et retourne le résultat.
* end termine la fonction.

### Comprendre la fonction reciprocal2

* local function reciprocal2(value) déclare une fonction locale nommée reciprocal2 qui accepte un unique paramètre value, qui est la valeur dont l'inverse sera retourné.
* if value == nil then créé un bloc conditionnel et test si la variable value est de type nil. Dans l'affirmative une erreur est générée.
* error('value must exist') génère une erreur avec la chaîne de caractère littérale comme message d'erreur (error statement). L'utilisation de la fonction error permet au programmeur de choisir le texte du message d'erreur qui sera retourné à la fonction ou à la page qui a invoqué la fonction.
    Lorsqu'une erreur est générée, l’exécution retourne immédiatement à la fonction appelante. Aucune instruction dans cette même fonction venant après l'erreur ne sera traitée.
* ...if tonumber(value) == nil créé un bloc conditionnel et test si la variable value est de type numérique. Dans la négative le code, tonumber retourne nil et une erreur est générée. (convertit en numerique et évalue si le résultat vaut zéro)...
* if tonumber(value) == 0 créé un bloc conditionnel et test si la variable value vaut 0. Dans l'affirmative une erreur est générée.
* return 1 / value retourne l'inverse de la valeur.
* end termine la fonction.

### Comprendre la fonction test2

* function p.test2(frame) et le code qui suit, déclare une fonction locale nommée test2 qui accepte un unique paramètre frame, qui est l'objet utile pour accéder aux paramètres passés par #invoke.
* local value = frame.args[1] définit une variable locale nommée value et lui assigne la valeur du premier argument (paramètre) de l’objet "frame" passé par #invoke.
* return reciprocal2(value) appel la fonction reciprocal2, en lui passant la variable value et retourne le résultat.
* end termine la fonction.

### Comprendre la fonction reciprocal3

* local function reciprocal3(value) déclare une fonction locale nommée reciprocal3 qui accepte un unique paramètre value, qui est la valeur dont l'inverse sera retourné.
* ...assert(value, 'value must exist') créé une condition interne qui test si la variable value est de type nil Dans l'affirmative une erreur est générée...
    L'usage de assert fait partie des meilleures pratiques pour documenter et tester les postulats sur les variables passées en paramètres.
* assert(tonumber(value), 'value must be a number') créé une condition interne qui test si la variable value est de type numérique. Dans la négative, tonumber retourne nil, une erreur est générée.
* assert(tonumber(value) ~= 0, 'value must not be zero') créé une condition interne qui test si la variable value vaut 0. Dans l'affirmative une erreur est générée.
* return 1 / value retourne l'inverse de la valeur.
* end termine la fonction.

### Comprendre la fonction test3

* function p.test3(frame) et le code qui suit, déclare une fonction locale nommée test3 qui accepte un unique paramètre frame, qui est l'objet utile pour accéder aux paramètres passés par #invoke.
* local value = frame.args[1] définit une variable locale nommée value et lui assigne la valeur du premier argument (paramètre) de l’objet "frame" passé par #invoke.
* return reciprocal3(value) appel la fonction reciprocal3, en lui passant la variable value et retourne le résultat.
* end termine la fonction.

### Comprendre la fonction test4

* function p.test4(frame) et le code qui suit, déclare une fonction locale nommée test4 qui accepte un unique paramètre frame, qui est l'objet utile pour accéder aux paramètres passés par #invoke.
* local value = frame.args[1] définit une variable locale nommée value et lui assigne la valeur du premier argument (paramètre) de l’objet "frame" passé par #invoke.
* if pcall(function result = reciprocal3(value) end) then créé une condition interne qui appel la fonction reciprocal3, lui passe la variable value et stocke le résultat. Si aucune erreur ne se produit, la variable result est retournée. Si une erreur se produit, une chaine de caractère est renvoyé comme message d'erreur.
* pcall utilise la fonction prédéfinie pcall (protected call) pour appeler une seconde fonction et intercepter les erreurs qui ont lieu.
* function ... end créé une fonction interne anonyme qui exécute le code dans ... comme un appel de fonction.
    La fonction anonyme est nécessaire pour enregistrer le resultat de la fonction reciprocal3 alors que la fonction pcall sert à intercepter n'importe quelle erreur qui se produit.
* end termine la fonction.

## Conclusion

Félicitation! Vous êtes capable de créer, tester et comprendre un script Lua qui contient un système de gestion des erreurs et exceptions. Continuez avec la leçon suivante Fonctions mathématiques ou choisissez l'étude d'une autre bibliothèque Lua ou Scribunto dans la barre verticale.