xpcall och meddelandehanterare
Använd xpcall med en anpassad hanterare för detaljerade felspårningar.
xpcall och meddelandehanterare är en gratis lektion i Lua Academy på CoddyKit. Detta är lektion 3 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Lua Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Lua Academy innehåller totalt 4 lektioner.
xpcall-syntax
xpcall(f, handler, ...) anropar f med argumenten ... i skyddat läge och anropar vid fel handler(errorObject). Hanterarens returvärde blir xpcalls andra returvärde. Till skillnad från pcall kör xpcall hanteraren medan stacken fortfarande är intakt.
local function handler(err)
return "HANDLED: " .. tostring(err)
end
local ok, msg = xpcall(
function() error("something bad") end,
handler
)
print(ok) -- false
print(msg) -- HANDLED: ...: something baddebug.traceback som hanterare
Den vanligaste xpcall-hanteraren är debug.traceback. Skicka den direkt som hanterare — den formaterar felet med en fullständig anropsstackspårning, vilket är ovärderligt vid felsökning av fel i produktionsmiljö.
local function level3() error("deep error") end
local function level2() level3() end
local function level1() level2() end
local ok, err = xpcall(level1, debug.traceback)
if not ok then
-- err contains the full stack trace
print(err)
endAnpassad hanterare med sammanhang
En anpassad hanterare kan lägga till sammanhang: tidsstämpel, loggning till fil och avisering till övervakningssystem, och därefter returnera det formaterade felet. Detta är standardmönstret för felhantering i Lua-applikationer i produktionsmiljö.
local function errorHandler(err)
local trace = debug.traceback(err, 2)
local ts = os.date("%H:%M:%S")
local report = string.format("[%s] ERROR\n%s", ts, trace)
-- Could log to file here
io.stderr:write(report .. "\n")
return report
end
local ok, msg = xpcall(
function()
local t = nil
return t.field -- error!
end,
errorHandler
)
print("ok:", ok)Hanteraren får inte ge fel
Om meddelandehanteraren själv ger ett fel returnerar Lua en felindikator utan att anropa hanteraren igen. Skriv alltid hanterare som är robusta — använd ingen I/O som kan misslyckas och ingen indexering av nil.
local function safeHandler(err)
-- Keep handler simple and safe
local ok, trace = pcall(debug.traceback, err, 2)
if ok then return trace
else return tostring(err) .. " (traceback failed)"
end
end
local ok, msg = xpcall(
function() error({complex="error table"}) end,
safeHandler
)
print(ok, type(msg))xpcall för huvudloopen
I långvariga program (servrar, spell loopar) kan ni omsluta huvudfunktionen med xpcall för att fånga och logga fel som annars skulle förbli ohanterade, utan att programmet kraschar. Huvudloopen kan sedan avgöra om den ska startas om eller avslutas.
local function mainApp()
-- simulate work
for i = 1, 3 do
print("Tick", i)
if i == 2 then error("transient error") end
end
end
local function handler(e)
return debug.traceback("App error: "..tostring(e), 2)
end
local ok, err = xpcall(mainApp, handler)
if not ok then
print("Application crashed:\n" .. err)
endStrukturerad felrapportering
Kombinera xpcall med strukturerade felobjekt och en omfattande hanterare för att skapa detaljerade och användbara felrapporter för felsökning eller övervakningspaneler.
local function handler(err)
local info = {
error = tostring(err),
time = os.date("!%Y-%m-%dT%H:%M:%SZ"),
trace = debug.traceback(nil, 2),
}
return info
end
local ok, report = xpcall(
function() error({code=500, msg="internal error"}) end,
handler
)
if not ok then
print("Time:", report.time)
print("Error:", report.error)
-- print("Trace:", report.trace)
endxpcall för coroutines
Inuti en coroutine fungerar pcall normalt. Om ni vill få stackspårningar från fel inuti coroutines omsluter ni coroutine-kroppen med xpcall. Hanteraren körs i coroutine-stackens sammanhang.
local function co_body()
error("error inside coroutine")
end
local co = coroutine.create(function()
local ok, err = xpcall(co_body, debug.traceback)
if not ok then
print("Caught in coroutine:", err:match("([^\n]+)"))
end
end)
coroutine.resume(co)Utökning av felobjekt
Hanteraren kan omvandla ett enkelt strängfel till ett omfattande objekt eller bygga ut ett redan omfattande objekt ytterligare. På så sätt kan kod på lägre nivå kasta enkla fel medan hanteraren lägger till sammanhang (begärande-ID, användarsession, miljöinformation).
local requestID = "req-123"
local function handler(err)
if type(err) == "string" then
return {message=err, requestID=requestID, level="error"}
end
err.requestID = requestID
return err
end
local ok, result = xpcall(
function() error("database timeout") end,
handler
)
if not ok then
print(result.message, result.requestID)
-- database timeout req-123
endJämförelse mellan pcall och xpcall
Använd pcall när: ni bara behöver felvärdet, felet förväntas och hanteras direkt, eller enkelhet är viktigt. Använd xpcall när: ni behöver stackspårningar, befinner er vid en toppnivågräns eller vill lägga till sammanhang i alla fel.
-- pcall: simple, no overhead
local ok, err = pcall(function()
return 1/0 -- no error in Lua! returns inf
end)
print(ok, err) -- true inf
-- xpcall: adds traceback
local ok2, err2 = xpcall(
function() error("real error") end,
debug.traceback
)
print(ok2) -- false
print(err2:sub(1,40)) -- first line of tracebackHanterarens returvärde
Vad hanteraren än returnerar blir xpcalls andra värde. Om hanteraren returnerar nil blir xpcalls andra returvärde nil. En hanterare som returnerar det ursprungliga felobjektet tillsammans med extra information är det mest flexibla alternativet.
local function enrichedHandler(err)
return {
original = err,
traceback = debug.traceback(nil, 2),
timestamp = os.time(),
}
end
local ok, report = xpcall(
function() error("oops") end,
enrichedHandler
)
if not ok then
print(type(report)) -- table
print(report.original) -- ...: oops
print(report.timestamp > 0) -- true
endSnabbkontroll
Vilken är den viktigaste fördelen med xpcall jämfört med pcall?
Sammanfattning: xpcall
Sammanfattning:
xpcall(f, handler, ...)— hanteraren körs medan stacken är intakt- Använd
debug.tracebacksom hanterare för fullständiga stackspårningar - Hanteraren får inte ge fel — håll den enkel
- Berika fel med sammanhang i hanteraren
- Omslut huvudloopar och serverhanterare med xpcall
- Hanterarens returvärde blir xpcalls andra returvärde
Lär dig Lua med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 40
- Lektioner
- 159
Vanliga frågor
Är lektionen ”xpcall och meddelandehanterare” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Lua Academy, inklusive ”xpcall och meddelandehanterare”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Lua Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”xpcall och meddelandehanterare”?
Använd xpcall med en anpassad hanterare för detaljerade felspårningar. Ni övar på Lua Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Lua Academy?
Du behöver inga förkunskaper. Utbildningen i Lua Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.
Hur lång tid tar lektionen ”xpcall och meddelandehanterare”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Lua Academy-lektionen?
Ja. Varje Lua Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Funktionen error()
- Skyddade anrop med pcall
- xpcall och meddelandehanterare
- Strukturerade felobjekt