Appels protégés avec pcall
Interceptez les erreurs en toute sécurité avec pcall et interprétez les valeurs renvoyées.
Appels protégés avec pcall est une leçon Lua Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Lua Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Lua Academy comprend 4 leçons au total.
Bases de pcall
pcall(f, ...) appelle la fonction f avec les arguments ... en mode protégé. Si f réussit, pcall renvoie true, suivi de toutes les valeurs renvoyées. Si f génère une erreur, pcall renvoie false, suivi du message d’erreur. Le programme continue dans les deux cas.
local function risky(x)
if x < 0 then error("negative input: " .. x) end
return math.sqrt(x)
end
local ok, result = pcall(risky, 9)
print(ok, result) -- true 3.0
ok, result = pcall(risky, -1)
print(ok, result) -- false ...: negative input: -1Intercepter des erreurs spécifiques
Après pcall, vérifiez le type de la valeur d’erreur pour traiter différemment les différents types d’erreurs. Les erreurs sous forme de table contiennent des données structurées ; les erreurs sous forme de chaîne contiennent un message. Gérez toujours les deux cas.
local function op(errType)
if errType == "table" then
error({code=42, msg="structured error"})
else
error("plain string error")
end
end
local ok, err = pcall(op, "table")
if not ok then
if type(err) == "table" then
print("Code:", err.code, "Msg:", err.msg)
else
print("String error:", err)
end
endPlusieurs valeurs renvoyées en cas de réussite
En cas de réussite, pcall renvoie toutes les valeurs renvoyées par la fonction protégée après le true initial. Capturez-les dans plusieurs variables.
local function compute(a, b)
return a + b, a * b, a - b
end
local ok, sum, product, diff = pcall(compute, 6, 4)
if ok then
print("sum:", sum, "product:", product, "diff:", diff)
-- sum: 10 product: 24 diff: 2
endImbrication de pcall
Les appels à pcall peuvent être imbriqués. Chaque pcall crée une portée protégée indépendante. Une erreur dans un pcall interne est interceptée par celui-ci, et non par le pcall externe. Cela vous permet d’implémenter des stratégies de repli.
local function tryPrimary()
error("primary failed")
end
local function tryFallback()
return "fallback result"
end
local ok, result = pcall(tryPrimary)
if not ok then
print("Primary failed:", result)
ok, result = pcall(tryFallback)
end
if ok then print("Got:", result) end -- fallback resultpcall avec des méthodes
Pour appeler une méthode (syntaxe avec deux-points) via pcall, transmettez la fonction et l’objet comme premier argument. pcall(obj.method, obj, args...) ou encapsulez l’appel dans une fermeture.
local obj = {
x = 10,
compute = function(self, n)
if n == 0 then error("zero divisor") end
return self.x / n
end
}
-- Pass method + self explicitly
local ok, v = pcall(obj.compute, obj, 2)
print(ok, v) -- true 5.0
-- Or use a closure
ok, v = pcall(function() return obj:compute(0) end)
print(ok, v) -- false ...zero divisorpcall pour sécuriser les entrées-sorties
Encapsulez les opérations d’entrées-sorties dans pcall afin d’intercepter les erreurs inattendues du système d’exploitation. Renvoyez une paire résultat/erreur cohérente afin que les appelants puissent gérer les échecs correctement.
local function safeRead(path)
local ok, result = pcall(function()
local f = assert(io.open(path, "r"))
local content = f:read("a")
f:close()
return content
end)
if ok then return result
else return nil, result
end
end
local data, err = safeRead("config.txt")
if data then print("Read", #data, "bytes")
else print("Error:", err)
endSchéma de nouvelle tentative avec pcall
Réessayez une opération instable (requête réseau, écriture dans un fichier) jusqu’à N fois, en utilisant pcall pour intercepter les erreurs. Dans du code réel, attendez entre les nouvelles tentatives (ou utilisez des coroutines).
local function retry(fn, maxAttempts)
local attempts = 0
while attempts < maxAttempts do
attempts = attempts + 1
local ok, result = pcall(fn)
if ok then
print("Succeeded on attempt", attempts)
return result
end
print("Attempt", attempts, "failed:", result)
end
error("all " .. maxAttempts .. " attempts failed")
end
local n = 0
retry(function()
n = n + 1
if n < 3 then error("not ready") end
return "done"
end, 5)Stocker le résultat de pcall dans une table
Lorsque pcall est utilisé dans une boucle, stockez les résultats dans une table pour les analyser ultérieurement. Cela est utile pour les opérations par lots lorsque vous souhaitez traiter tous les éléments et recueillir les erreurs plutôt que de vous arrêter au premier échec.
local jobs = {10, -5, 25, 0, 16}
local results = {}
for _, n in ipairs(jobs) do
local ok, v = pcall(function()
if n < 0 then error("negative") end
return math.sqrt(n)
end)
results[#results+1] = {input=n, ok=ok, value=v}
end
for _, r in ipairs(results) do
if r.ok then
print(r.input, "->", string.format("%.3f", r.value))
else
print(r.input, "-> ERROR:", r.value)
end
endpcall ou xpcall
pcall intercepte l’erreur, mais ne vous fournit que la valeur d’erreur. xpcall vous permet de fournir une fonction gestionnaire de message qui s’exécute alors que la pile est encore intacte, ce qui permet d’obtenir des traces de pile. Choisissez xpcall lorsque vous avez besoin de traces d’appels.
-- pcall: simple, no traceback
local ok1, err1 = pcall(function()
error("simple error")
end)
print(err1) -- only the error message
-- xpcall: with traceback handler
local ok2, err2 = xpcall(
function() error("traced error") end,
function(e) return debug.traceback(e, 2) end
)
print(err2) -- full stack traceConvention de retour de pcall
Utilisez pcall comme base d’une API cohérente : renvoyez toujours value en cas de réussite, ou nil, errorMessage en cas d’échec. Organisez vos fonctions de cette manière afin que les appelants sachent toujours à quoi s’attendre.
local function loadJSON(path)
local ok, result = pcall(function()
local f = assert(io.open(path, "r"))
local text = f:read("a")
f:close()
-- Fake JSON parse for demo
return {data = text, path = path}
end)
if ok then return result
else return nil, result
end
end
local data, err = loadJSON("data.json")
if data then print("Loaded:", data.path)
else print("Failed:", err)
endVérification rapide
Que renvoie pcall lorsque la fonction protégée réussit ?
Récapitulatif : pcall
Résumé :
pcall(f, ...)→true, results...oufalse, err- Vérifiez la première valeur renvoyée pour déterminer la réussite ou l’échec
- Plusieurs valeurs sont renvoyées après true en cas de réussite
- pcall imbriqué : chacun intercepte indépendamment ses propres erreurs
- Schéma de nouvelle tentative : boucle avec pcall pour les opérations instables
- Utilisez xpcall lorsque vous avez besoin de traces de pile
Questions Fréquemment Posées
La leçon « Appels protégés avec pcall » est-elle gratuite ?
Oui — le texte complet de « Appels protégés avec pcall » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Lua Academy, passe à CoddyKit PRO. Le cours Lua Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Appels protégés avec pcall » ?
Interceptez les erreurs en toute sécurité avec pcall et interprétez les valeurs renvoyées. Tu pratiques Lua Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Lua Academy ?
Aucune expérience préalable n'est requise. Lua Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « Appels protégés avec pcall » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Lua Academy ?
Oui. Chaque leçon Lua Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- La fonction error()
- Appels protégés avec pcall
- xpcall et gestionnaires de messages
- Objets d’erreur structurés