0Pricing
Lua Academy · Leçon

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: -1

Intercepter 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
end

Plusieurs 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
end

Imbrication 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 result

pcall 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 divisor

pcall 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)
end

Sché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
end

pcall 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 trace

Convention 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)
end

Vérification rapide

Que renvoie pcall lorsque la fonction protégée réussit ?

Récapitulatif : pcall

Résumé :

  • pcall(f, ...) → true, results... ou false, 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

  1. La fonction error()
  2. Appels protégés avec pcall
  3. xpcall et gestionnaires de messages
  4. Objets d’erreur structurés
← Retour à Lua Academy