0Pricing
Lua Academy · Lezione

La funzione error()

Generi errori con error() e comprenda i livelli e i messaggi di errore.

La funzione error() è una lezione Lua Academy gratuita su CoddyKit. Questa è la lezione 1 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.

Generare errori

error(message, level) genera un errore Lua. L'esecuzione si interrompe e l'errore risale lo stack delle chiamate finché non viene catturato da pcall o xpcall, oppure finché il programma non termina. Il messaggio può essere un valore qualsiasi: stringa, tabella o numero.

local function divide(a, b)
  if b == 0 then
    error("division by zero")
  end
  return a / b
end

print(divide(10, 2))    -- 5.0
-- divide(10, 0)        -- ERROR: division by zero

Livelli degli errori

Il secondo argomento di error() controlla il punto a cui viene attribuito l'errore. Il livello 1 (predefinito) indica la chiamata a error(). Il livello 2 indica il chiamante. Il livello 0 non aggiunge informazioni sulla posizione. Usi il livello 2 nelle funzioni di libreria per attribuire l'errore al codice dell'utente.

local function assertPositive(n, name)
  if n <= 0 then
    error((name or "value") .. " must be positive, got " .. n, 2)
    -- level 2: blame the caller, not this function
  end
  return n
end

local function compute(x)
  assertPositive(x, "x")   -- error points here if x <= 0
  return math.sqrt(x)
end

compute(-5)  -- error: "x must be positive, got -5" at compute() call

Errori con oggetti tabella

Passare una tabella come valore dell'errore consente ai chiamanti di esaminare informazioni strutturate sull'errore: codice, messaggio e contesto. È più informativo di una semplice stringa e permette di gestire gli errori a livello programmatico.

local function openDB(host, port)
  if port < 1 or port > 65535 then
    error({code="INVALID_PORT", port=port,
           msg="port out of range: " .. port})
  end
  -- ... connect
  return {host=host, port=port}
end

local ok, err = pcall(openDB, "localhost", -1)
if not ok and type(err) == "table" then
  print("Code:", err.code)    -- INVALID_PORT
  print("Port:", err.port)    -- -1
  print("Msg:", err.msg)
end

assert() come scorciatoia sintattica

assert(v, msg) equivale a if not v then error(msg, 2) end; return v, .... È idiomatico usarlo per verificare le precondizioni. Se v è valutato come vero, assert restituisce tutti i suoi argomenti (utile per concatenare le chiamate).

local function sqrt(n)
  assert(type(n) == "number", "expected number, got " .. type(n))
  assert(n >= 0, "sqrt of negative: " .. n)
  return math.sqrt(n)
end

print(sqrt(16))    -- 4.0
print(sqrt(2))     -- 1.4142...
-- sqrt("hi")      -- ERROR: expected number, got string

error() contro return nil,err

Esistono due convenzioni per segnalare un errore: error() (stile eccezione) oppure return nil, msg (stile funzionale). Usi error() per condizioni realmente impreviste (bug di programmazione, violazioni dei contratti). Usi nil, msg per gli errori previsti (file non trovato, timeout di rete).

-- Exception style (programming error)
local function mustExist(t, key)
  local v = t[key]
  if v == nil then error("required key missing: " .. key, 2) end
  return v
end

-- Functional style (expected failure)
local function findUser(id)
  -- ... database query
  return nil, "user not found"  -- expected: user may not exist
end

Errori nei metametodi

Gli errori possono essere generati all'interno dei metametodi. Se un metametodo genera un errore, questo si propaga al codice che ha attivato l'operazione (ad esempio un'espressione aritmetica). Gestisca sempre gli input non validi nei metametodi.

local SafeDiv = {}
SafeDiv.__index = SafeDiv

SafeDiv.__div = function(a, b)
  if b.value == 0 then
    error("SafeDiv: division by zero", 2)
  end
  return SafeDiv.new(a.value / b.value)
end

function SafeDiv.new(v)
  return setmetatable({value=v}, SafeDiv)
end

local a = SafeDiv.new(10)
local b = SafeDiv.new(0)
local ok, err = pcall(function() return a / b end)
print(ok, err)

Tipi di errore personalizzati

Crei un helper per costruire oggetti di errore tipizzati. Includa un identificatore del tipo, così chi chiama la funzione può distinguere tra diversi tipi di errore e gestirli in modo appropriato.

local function newError(kind, msg, extra)
  return setmetatable(
    {kind=kind, message=msg, extra=extra},
    {__tostring = function(e)
      return "[" .. e.kind .. "] " .. e.message
    end}
  )
end

local E = {
  notFound = function(name) return newError("NOT_FOUND","not found: "..name) end,
  badInput = function(msg)  return newError("BAD_INPUT", msg) end,
}

local ok, err = pcall(error, E.notFound("config.json"))
if not ok then print(err.kind, err.message) end

Propagazione degli errori

Quando una funzione ne chiama un'altra che genera un errore, l'errore si propaga automaticamente lungo lo stack. Non è necessario rilanciarlo: è sufficiente non intercettarlo. Intercetti gli errori solo al livello in cui può gestirli o segnalarli in modo significativo.

local function step3() error("step3 failed") end
local function step2() step3() end
local function step1() step2() end

local ok, err = pcall(step1)
if not ok then
  -- err includes the source location
  print("Caught at top level:", err)
end
-- Error: input:1: step3 failed

Stack trace con debug.traceback

Un semplice error() fornisce una sola riga di contesto. Per ottenere uno stack trace completo, usi debug.traceback(msg) come valore dell'errore. In genere questa operazione viene eseguita in un gestore di xpcall.

local function buggy()
  local t = nil
  return t.field   -- nil indexing: error
end

local ok, err = xpcall(buggy, function(e)
  return debug.traceback(e, 2)  -- full stack trace
end)

if not ok then
  print(err)  -- full traceback
end

Rilancio degli errori

A volte si intercetta un errore per aggiungere contesto e poi lo si rilancia. Usi error(err, 0) (livello 0) quando rilancia un errore stringa, per evitare di aggiungere un altro prefisso di posizione a un messaggio già formattato.

local function loadAndParse(path)
  local ok, err = pcall(function()
    local f = io.open(path, "r")
    if not f then error("cannot open: " .. path) end
    local content = f:read("a")
    f:close()
    return content
  end)
  if not ok then
    error("loadAndParse failed: " .. err, 0)  -- re-raise with context
  end
end

local ok2, msg = pcall(loadAndParse, "missing.txt")
print(ok2, msg)

Verifica rapida

Che cosa significa il livello 2 in error("msg", 2)?

Riepilogo: error()

Riepilogo:

  • error(msg, level) — genera un errore; il livello 2 attribuisce la responsabilità al chiamante
  • Usi le tabelle per errori strutturati con tipo e contesto
  • assert(v, msg) — verifica idiomatica di una precondizione
  • Usi error() per i bug; restituisca nil+err per gli errori previsti
  • Rilanci con error(err, 0) per preservare il formato del messaggio

Domande Frequenti

La lezione «La funzione error()» è gratuita?

Sì — il testo completo di «La funzione error()» è 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 «La funzione error()»?

Generi errori con error() e comprenda i livelli e i messaggi di errore. 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 1 di 4.

Quanto tempo richiede la lezione «La funzione error()»?

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