Lua Academy · Pelajaran

Fungsi error()

Cetuskan ralat dengan error() dan fahami tahap serta mesej ralat.

Pelajaran 1 daripada 412 langkah

Fungsi error() ialah pelajaran Lua Academy percuma di CoddyKit. Ini ialah pelajaran 1 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Lua Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Lua Academy merangkumi sejumlah 4 pelajaran.

Mencetuskan Ralat

error(message, level) mencetuskan ralat Lua. Pelaksanaan berhenti dan ralat itu disebarkan ke atas susunan panggilan sehingga ditangkap oleh pcall atau xpcall, atau sehingga atur cara ditamatkan. Mesej boleh berupa apa-apa nilai — rentetan, jadual atau nombor.

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

Tahap Ralat

Argumen kedua kepada error() mengawal lokasi pelaporan ralat. Tahap 1 (lalai) menunjuk kepada panggilan error() itu sendiri. Tahap 2 menunjuk kepada pemanggil. Tahap 0 tidak menambah maklumat lokasi. Gunakan tahap 2 dalam fungsi pustaka supaya kod pengguna dikenal pasti sebagai punca.

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

Ralat dengan Objek Jadual

Menghantar jadual sebagai nilai ralat membolehkan pemanggil memeriksa maklumat ralat berstruktur: kod ralat, mesej dan konteks. Ini lebih bermaklumat berbanding rentetan biasa serta membolehkan pengendalian ralat secara terprogram.

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() sebagai Kemudahan Sintaks

assert(v, msg) setara dengan if not v then error(msg, 2) end; return v, .... Ia merupakan kaedah lazim untuk menyemak prasyarat. Jika v bernilai benar, assert mengembalikan semua argumennya (berguna untuk rantaian).

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() berbanding return nil,err

Dua konvensyen untuk menandakan kegagalan: error() (gaya pengecualian) atau return nil, msg (gaya fungsi). Gunakan error() untuk keadaan yang benar-benar tidak dijangka (pepijat pengaturcaraan, pelanggaran kontrak). Gunakan nil, msg untuk kegagalan yang dijangka (fail tidak ditemui, tamat masa rangkaian).

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

Ralat dalam Metakaedah

Ralat boleh dicetuskan di dalam metakaedah. Jika metakaedah menghasilkan ralat, ralat itu disebarkan kepada kod yang mencetuskan operasi tersebut (seperti ungkapan aritmetik). Sentiasa lindungi metakaedah daripada input yang tidak sah.

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)

Jenis Ralat Tersuai

Cipta pembantu untuk membina objek ralat yang mempunyai jenis. Sertakan tag jenis supaya pemanggil boleh membezakan pelbagai jenis ralat dan mengendalikannya dengan sewajarnya.

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

Penyebaran Ralat

Apabila fungsi memanggil fungsi lain yang menghasilkan ralat, ralat itu tersebar secara automatik ke atas dalam tindanan. Anda tidak perlu menjana semula ralat — jangan tangkapnya sahaja. Tangkap ralat hanya pada peringkat yang membolehkan Anda mengendalikannya atau melaporkannya dengan bermakna.

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

Jejak Tindanan dengan debug.traceback

error() biasa memberikan satu baris konteks. Untuk mendapatkan jejak tindanan penuh, gunakan debug.traceback(msg) sebagai nilai ralat. Lazimnya, ini dilakukan dalam pengendali 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

Menjana Semula Ralat

Kadangkala Anda menangkap ralat untuk menambahkan konteks, kemudian menjana semula ralat itu. Gunakan error(err, 0) (aras 0) apabila menjana semula ralat rentetan supaya awalan lokasi tambahan tidak ditambah pada mesej yang telah diformatkan.

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)

Semakan Pantas

Apakah maksud aras 2 dalam error("msg", 2)?

Imbas Kembali: error()

Ringkasan:

  • error(msg, level) — jana ralat; aras 2 menyalahkan pemanggil
  • Gunakan jadual untuk ralat berstruktur dengan jenis dan konteks
  • assert(v, msg) — pemeriksaan prasyarat yang lazim
  • Gunakan error() untuk pepijat; kembalikan nil+err untuk kegagalan yang dijangka
  • Jana semula dengan error(err, 0) untuk mengekalkan format mesej
Percuma untuk bermula

Pelajari Lua dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
40
Pelajaran
159

Soalan Lazim

Adakah pelajaran “Fungsi error()” percuma?

Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Lua Academy, termasuk “Fungsi error()”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Lua Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Fungsi error()”?

Cetuskan ralat dengan error() dan fahami tahap serta mesej ralat. Anda berlatih Lua Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Lua Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Lua Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 1 daripada 4.

Berapa lamakah pelajaran “Fungsi error()” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Lua Academy ini?

Ya. Setiap pelajaran Lua Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Fungsi error()
  2. Panggilan Terlindung dengan pcall
  3. xpcall dan Pengendali Mesej
  4. Objek Ralat Berstruktur
← Kembali ke Lua Academy