xpcall dan Penangan Pesan
Gunakan xpcall dengan penangan khusus untuk traceback galat yang terperinci.
xpcall dan Penangan Pesan adalah pelajaran Lua Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Lua Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Lua Academy mencakup 4 pelajaran total.
Sintaks xpcall
xpcall(f, handler, ...) memanggil f dengan argumen ... dalam mode terlindungi, dan saat terjadi error memanggil handler(errorObject). Nilai kembalian handler menjadi nilai kembalian kedua xpcall. Berbeda dengan pcall, xpcall menjalankan handler saat stack masih utuh.
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 sebagai Handler
Handler xpcall yang paling umum adalah debug.traceback. Teruskan langsung sebagai handler—fungsi ini memformat error dengan stack trace pemanggilan lengkap, yang sangat berguna untuk men-debug error dalam lingkungan produksi.
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)
endHandler Kustom dengan Konteks
Handler kustom dapat menambahkan konteks: stempel waktu, mencatat ke file, memberi tahu sistem pemantauan, lalu mengembalikan error yang telah diformat. Ini adalah pola standar untuk penanganan error produksi dalam aplikasi Lua.
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)Handler Tidak Boleh Menghasilkan Error
Jika handler pesan itu sendiri menghasilkan error, Lua mengembalikan penanda error tanpa memanggil handler lagi. Selalu tulis handler yang tahan segala kondisi—jangan gunakan IO yang dapat gagal atau pengindeksan 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 untuk Perulangan Utama
Dalam program yang berjalan lama (server, perulangan gim), bungkus fungsi utama dalam xpcall untuk menangkap dan mencatat error yang tidak tertangani tanpa menyebabkan program berhenti. Perulangan utama kemudian dapat menentukan apakah harus dimulai ulang atau keluar.
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)
endPelaporan Error Terstruktur
Gabungkan xpcall dengan objek error terstruktur dan handler yang kaya untuk menghasilkan laporan error yang terperinci dan dapat ditindaklanjuti guna keperluan debugging atau dasbor pemantauan.
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 untuk Coroutine
Di dalam coroutine, pcall bekerja secara normal. Untuk memperoleh traceback dari error di dalam coroutine, bungkus isi coroutine dalam xpcall. Handler berjalan dalam konteks stack coroutine.
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)Pengayaan Objek Error
Handler dapat mengubah error string biasa menjadi objek kaya, atau memperkaya objek kaya lebih lanjut. Dengan demikian, kode tingkat rendah dapat melempar error sederhana, sementara handler menambahkan konteks (ID permintaan, sesi pengguna, informasi lingkungan).
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
endMembandingkan pcall dan xpcall
Gunakan pcall ketika: Anda hanya memerlukan nilai error, error diperkirakan dan ditangani langsung, atau kesederhanaan penting. Gunakan xpcall ketika: Anda memerlukan stack trace, berada di batas tingkat atas, atau ingin menambahkan konteks ke semua error.
-- 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 tracebackNilai Kembalian Handler
Apa pun yang dikembalikan handler menjadi nilai kedua dari xpcall. Jika handler mengembalikan nil, kembalian kedua xpcall adalah nil. Handler yang mengembalikan objek error asli beserta informasi tambahan merupakan pendekatan yang paling fleksibel.
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
endPemeriksaan Singkat
Apa keunggulan utama xpcall dibandingkan pcall?
Rangkuman: xpcall
Rangkuman:
xpcall(f, handler, ...)— handler berjalan saat stack masih utuh- Gunakan
debug.tracebacksebagai handler untuk traceback lengkap - Handler tidak boleh menghasilkan error—buat sesederhana mungkin
- Perkaya error dengan konteks di dalam handler
- Bungkus perulangan utama atau handler server dalam xpcall
- Kembalian handler menjadi nilai kembalian kedua xpcall
Pertanyaan yang Sering Diajukan
Apakah pelajaran “xpcall dan Penangan Pesan” gratis?
Ya — teks lengkap “xpcall dan Penangan Pesan” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Lua Academy, upgrade ke CoddyKit PRO. Kursus Lua Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “xpcall dan Penangan Pesan”?
Gunakan xpcall dengan penangan khusus untuk traceback galat yang terperinci. Kamu berlatih Lua Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Lua Academy?
Tidak diperlukan pengalaman sebelumnya. Lua Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “xpcall dan Penangan Pesan” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Lua Academy ini?
Ya. Setiap pelajaran Lua Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Fungsi error()
- Pemanggilan Terlindungi dengan pcall
- xpcall dan Penangan Pesan
- Objek Galat Terstruktur