0Pricing
Lua Academy · Pelajaran

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 bad

debug.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)
end

Handler 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)
end

Pelaporan 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)
end

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

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

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

Pemeriksaan Singkat

Apa keunggulan utama xpcall dibandingkan pcall?

Rangkuman: xpcall

Rangkuman:

  • xpcall(f, handler, ...) — handler berjalan saat stack masih utuh
  • Gunakan debug.traceback sebagai 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

  1. Fungsi error()
  2. Pemanggilan Terlindungi dengan pcall
  3. xpcall dan Penangan Pesan
  4. Objek Galat Terstruktur
← Kembali ke Lua Academy