Chamadas protegidas com pcall
Capture erros com segurança usando pcall e interprete os valores retornados.
Chamadas protegidas com pcall é uma aula grátis de Lua Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Lua Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Lua Academy inclui 4 aulas no total.
Noções básicas de pcall
pcall(f, ...) chama a função f com os argumentos ... em modo protegido. Se f for concluída com sucesso, pcall retorna true seguido de todos os valores retornados. Se f gerar um erro, pcall retorna false seguido da mensagem de erro. O programa continua de qualquer forma.
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: -1Captura de erros específicos
Verifique o tipo do valor do erro após pcall para tratar diferentes tipos de erro de maneiras diferentes. Erros em tabelas contêm dados estruturados; erros em strings contêm uma mensagem. Sempre trate os dois casos.
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
endVários valores retornados em caso de sucesso
Em caso de sucesso, pcall retorna todos os valores retornados pela função protegida depois do true inicial. Capture-os com várias variáveis.
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
endAninhamento de pcall
As chamadas de pcall podem ser aninhadas. Cada pcall cria um escopo protegido independente. Um erro em um pcall interno é capturado pelo pcall interno, não pelo externo. Isso permite implementar estratégias de contingência.
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 com métodos
Para chamar um método (sintaxe com dois-pontos) por meio de pcall, passe a função e o objeto como primeiro argumento. pcall(obj.method, obj, args...) ou envolva a chamada em um fechamento.
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 para segurança de E/S
Envolva as operações de E/S em pcall para capturar erros inesperados do OS. Retorne um par consistente de resultado e erro para que os chamadores possam tratar as falhas com elegância.
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)
endPadrão de repetição com pcall
Repita uma operação instável (uma solicitação de rede ou gravação de arquivo) até N vezes, usando pcall para capturar os erros. Em código real, aguarde entre as tentativas (ou use corrotinas).
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)Armazenamento de resultados de pcall em uma tabela
Quando pcall é usado em um laço, armazene os resultados em uma tabela para analisá-los posteriormente. Isso é útil em operações em lote nas quais você deseja processar todos os itens e coletar os erros, em vez de parar na primeira falha.
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 versus xpcall
pcall captura o erro, mas fornece apenas o valor do erro. xpcall permite fornecer uma função manipuladora de mensagens que é executada enquanto a pilha ainda está intacta, possibilitando rastreamentos da pilha. Escolha xpcall quando precisar de rastreamentos.
-- 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 traceConvenção de retorno de pcall
Use pcall como base para uma API consistente: sempre retorne value em caso de sucesso ou nil, errorMessage em caso de falha. Estruture suas funções dessa maneira para que os chamadores sempre saibam o que esperar.
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)
endVerificação rápida
O que pcall retorna quando a função protegida é concluída com sucesso?
Recapitulação: pcall
Resumo:
pcall(f, ...)→true, results...oufalse, err- Verifique o primeiro retorno para determinar sucesso ou falha
- Em caso de sucesso, há vários valores retornados depois de true
- pcall aninhado: cada chamada captura seus próprios erros de forma independente
- Padrão de repetição: use um laço com pcall para operações instáveis
- Use xpcall quando precisar de rastreamentos da pilha
Aprenda Lua com um tutor de IA — grátis
Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.
- Cursos
- 40
- Aulas
- 159
Perguntas Frequentes
A aula “Chamadas protegidas com pcall” é grátis?
Sim — o texto completo de “Chamadas protegidas com pcall” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Lua Academy, atualize para CoddyKit PRO. O curso de Lua Academy inclui 4 aulas no total.
O que vou aprender em “Chamadas protegidas com pcall”?
Capture erros com segurança usando pcall e interprete os valores retornados. Você pratica Lua Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Lua Academy?
Nenhuma experiência prévia é necessária. Lua Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “Chamadas protegidas com pcall”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Lua Academy?
Sim. Cada aula de Lua Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- A função error()
- Chamadas protegidas com pcall
- xpcall e manipuladores de mensagens
- Objetos de erro estruturados