0Pricing
Lua Academy · Lezione

Chiamate protette con pcall

Intercetti gli errori in modo sicuro usando pcall e interpreti i valori restituiti.

Chiamate protette con pcall è una lezione Lua Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Lua Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Lua Academy include 4 lezioni in totale.

Nozioni di base su pcall

pcall(f, ...) chiama la funzione f con gli argomenti ... in modalità protetta. Se f termina correttamente, pcall restituisce true seguito da tutti i valori restituiti. Se f genera un errore, pcall restituisce false seguito dal messaggio di errore. In entrambi i casi, il programma continua.

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

Intercettazione di errori specifici

Controlli il tipo del valore dell'errore dopo pcall per gestire diversamente i vari tipi di errore. Gli errori rappresentati da tabelle contengono dati strutturati, mentre gli errori stringa contengono un messaggio. Gestisca sempre entrambi i casi.

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

Più valori restituiti in caso di successo

In caso di successo, pcall restituisce tutti i valori restituiti dalla funzione protetta dopo il true iniziale. Li acquisisca usando più variabili.

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

Annidamento di pcall

Le chiamate a pcall possono essere annidate. Ogni pcall crea un ambito protetto indipendente. Un errore in un pcall interno viene intercettato dal pcall interno, non da quello esterno. Questo consente di implementare strategie di fallback.

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 con i metodi

Per chiamare un metodo (sintassi con i due punti) tramite pcall, passi la funzione e l'oggetto come primo argomento. pcall(obj.method, obj, args...) oppure racchiuda la chiamata in una closure.

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 per la sicurezza delle operazioni di I/O

Racchiuda le operazioni di I/O in pcall per intercettare gli errori imprevisti del sistema operativo. Restituisca una coppia risultato/errore coerente, così chi chiama la funzione può gestire gli errori in modo appropriato.

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

Schema di ritentativo con pcall

Ripeta un'operazione instabile (una richiesta di rete o una scrittura su file) fino a N volte, usando pcall per intercettare gli errori. Nel codice reale, attenda tra un tentativo e l'altro (oppure usi le coroutine).

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)

Acquisizione dei risultati di pcall in una tabella

Quando usa pcall in un ciclo, memorizzi i risultati in una tabella per analizzarli in seguito. È utile per le operazioni batch in cui desidera elaborare tutti gli elementi e raccogliere gli errori invece di interrompersi al primo errore.

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 e xpcall a confronto

pcall intercetta l'errore, ma fornisce solo il valore dell'errore. xpcall consente di specificare una funzione gestore dei messaggi che viene eseguita mentre lo stack è ancora intatto, rendendo possibili gli stack trace. Scelga xpcall quando ha bisogno dei traceback.

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

Convenzione dei valori restituiti da pcall

Usi pcall come base per un'API coerente: restituisca sempre value in caso di successo oppure nil, errorMessage in caso di errore. Strutturi le funzioni in questo modo, così chi le chiama sa sempre che cosa aspettarsi.

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

Verifica rapida

Che cosa restituisce pcall quando la funzione protetta termina correttamente?

Riepilogo: pcall

Riepilogo:

  • pcall(f, ...) → true, results... oppure false, err
  • Controlli il primo valore restituito per determinare il successo o il fallimento
  • In caso di successo, dopo true vengono restituiti più valori
  • pcall annidati: ciascuno intercetta indipendentemente i propri errori
  • Schema di ritentativo: usi un ciclo con pcall per le operazioni instabili
  • Usi xpcall quando ha bisogno degli stack trace

Domande Frequenti

La lezione «Chiamate protette con pcall» è gratuita?

Sì — il testo completo di «Chiamate protette con pcall» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Lua Academy, passa a CoddyKit PRO. Il corso Lua Academy include 4 lezioni in totale.

Cosa imparerò in «Chiamate protette con pcall»?

Intercetti gli errori in modo sicuro usando pcall e interpreti i valori restituiti. Eserciti Lua Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Lua Academy?

Non è richiesta alcuna esperienza precedente. Lua Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Chiamate protette con pcall»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Lua Academy?

Sì. Ogni lezione Lua Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. La funzione error()
  2. Chiamate protette con pcall
  3. xpcall e gestori dei messaggi
  4. Oggetti di errore strutturati
← Torna a Lua Academy