Gestion des erreurs Lua

La gestion des erreurs pendant l'exécution d'un programme est nécessaire. Des erreurs inattendues peuvent survenir lors d'opérations sur des fichiers, de transferts de données et d'appels à des services web. Si les informations d'erreur ne sont pas traitées correctement, cela peut entraîner une fuite d'informations, une défaillance du programme et d'autres problèmes.

Tout langage de programmation nécessite une gestion des erreurs. Les types d'erreurs incluent :

  • Erreurs de syntaxe
  • Erreurs d'exécution

Erreurs de syntaxe

Les erreurs de syntaxe sont généralement causées par une utilisation incorrecte des composants du programme (comme les opérateurs et les expressions). Un exemple simple est le suivant :

-- test.lua 文件
a == 2

Le résultat d'exécution du code ci-dessus est :

lua: test.lua:2: syntax error near '=='

Comme vous pouvez le voir, une erreur de syntaxe s'est produite ci-dessus ; un signe "=" est différent de deux signes "=". Un "=" est une expression d'affectation, tandis que deux "=" forment une opération de comparaison.

Un autre exemple :

Exemple

for a= 1,10
   print(a)
end

L'exécution du programme ci-dessus produira l'erreur suivante :

lua: test2.lua:2: 'do' expected near 'print'

Les erreurs de syntaxe sont plus simples que les erreurs d'exécution d'un programme. Les erreurs d'exécution ne permettent pas de localiser l'erreur spécifique, mais les erreurs de syntaxe peuvent être résolues rapidement. Par exemple, dans l'exemple ci-dessus, nous avons juste besoin d'ajouter "do" sous l'instruction for :

Exemple

for a= 1,10
do
   print(a)
end

Erreurs d'exécution

Une erreur d'exécution se produit lorsque le programme s'exécute normalement mais affiche un message d'erreur. L'exemple suivant signale une erreur pendant l'exécution en raison d'une saisie de paramètre incorrecte :

function add(a,b)
   return a+b
end

add(10)

Lorsque nous compilons et exécutons le code suivant, la compilation peut réussir, mais l'erreur suivante se produira à l'exécution :

lua: test2.lua:2: attempt to perform arithmetic on local 'b' (a nil value)
stack traceback:
    test2.lua:2: in function 'add'
    test2.lua:5: in main chunk
    [C]: ?

En Lua, lors de l'appel d'une fonction, même si la liste des paramètres effectifs et la liste des paramètres formels ne correspondent pas, l'appel peut toujours réussir. Les paramètres excédentaires seront ignorés, et les paramètres manquants seront remplis avec nil.

Le message d'erreur ci-dessus est dû au fait que le paramètre b est rempli avec nil, et que nil participe à l'opération +.

Siaddà l'intérieur de la fonction n'est pas"return a+b"mais plutôt"print(a,b)"alors le résultat devient"10 nil"aucune erreur ne sera signalée.


Gestion des erreurs

Nous pouvons utiliser deux fonctions : assert et error pour gérer les erreurs. Voici un exemple :

Exemple

local function add(a,b)
   assert(type(a) == "number", "a is not a number")
   assert(type(b) == "number", "b is not a number")
   return a+b
end
ajoutez(10)

L'exécution du programme ci-dessus produira l'erreur suivante :

lua: test.lua:3: b 不是一个数字
stack traceback:
    [C]: in function 'assert'
    test.lua:3: in local 'add'
    test.lua:6: in main chunk
    [C]: in ?

Dans l'exemple, assert vérifie d'abord le premier paramètre. S'il n'y a pas de problème, assert ne fait rien ; sinon, assert lève le deuxième paramètre comme message d'erreur.

Fonction error

Format de syntaxe:

error (message [, level])

Fonction : termine la fonction en cours d'exécution et renvoie le contenu de message comme message d'erreur (la fonction error ne retourne jamais)

Normalement, error ajoute certaines informations de localisation d'erreur au début du message.

Le paramètre Level indique où obtenir l'emplacement de l'erreur :

  • Level=1 [par défaut] : la position de l'appel à error (fichier + numéro de ligne)
  • Level=2 : indique quelle fonction a appelé la fonction qui appelle error
  • Level=0 : ne pas ajouter d'informations de localisation d'erreur

pcall et xpcall, debug

Pour gérer les erreurs en Lua, vous pouvez utiliser la fonction pcall (appel protégé) pour encapsuler le code qui doit être exécuté.

pcall reçoit une fonction et les paramètres à lui passer, puis l'exécute. Résultats d'exécution : avec erreur, sans erreur ; valeur de retour true ou false, errorinfo.

Le format de syntaxe est le suivant

if pcall(function_name, ….) then
-- 没有错误
else
-- 一些错误
end

Exemple simple :

Exemple

> =pcall(function(i) print(i) end, 33)
33
vrai
   
> =pcall(function(i) print(i) error('error..') end, 33)
33
false        stdin:1: error..
> function f() return false,2 end
> if f() then print '1' else print '0' end
0

pcall appelle le premier paramètre dans un « mode protégé », donc pcall peut intercepter toute erreur pendant l'exécution de la fonction.

Habituellement, lorsqu'une erreur se produit, vous voulez plus d'informations de débogage, pas seulement l'emplacement de l'erreur. Mais lorsque pcall retourne, il a déjà détruit une partie du contenu de la pile d'appels.

Lua fournit la fonction xpcall. xpcall reçoit un second paramètre — une fonction de gestion des erreurs. Lorsqu'une erreur se produit, Lua appelle la fonction de gestion des erreurs avant que la pile d'appels ne se déroule, afin que vous puissiez utiliser la bibliothèque debug dans cette fonction pour obtenir des informations supplémentaires sur l'erreur.

La bibliothèque debug fournit deux fonctions générales de gestion des erreurs :

  • debug.debug : fournit une invite Lua aux utilisateurs pour vérifier la cause de l'erreur
  • debug.traceback : construit un message d'erreur étendu basé sur la pile d'appels
>=xpcall(function(i) print(i) error('error..') end, function() print(debug.traceback()) end, 33)
33
stack traceback:
stdin:1: in function <stdin:1>
[C]: in function 'error'
stdin:1: in function <stdin:1>
[C]: in function 'xpcall'
stdin:1: in main chunk
[C]: in ?
false        nil

Exemple d'utilisation de xpcall 2 :

Exemple

function myfunction ()
   n = n/nil
end

function myerrorhandler( err )
   print( "ERROR:", err )
end

status = xpcall( myfunction, myerrorhandler )
print( status)

L'exécution du programme ci-dessus produira l'erreur suivante :

ERROR:    test2.lua:2: attempt to perform arithmetic on global 'n' (a nil value)
false
Autres extensions