Objek Ralat Berstruktur
Luluskan jadual sebagai objek ralat untuk menyampaikan jenis dan konteks.
Objek Ralat Berstruktur ialah pelajaran Lua Academy percuma di CoddyKit. Ini ialah pelajaran 4 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.
Mengapa Ralat Berstruktur?
Ralat rentetan biasa sukar dikendalikan secara terprogram. Objek ralat berstruktur (jadual) membawa maklumat jenis dan data konteks, serta boleh diperiksa dan diambil tindakan oleh pemanggil. Ini membolehkan penghantaran berasaskan ralat tanpa menghuraikan rentetan.
-- Plain string: hard to handle programmatically
error("database error: connection refused")
-- Structured: type + data
error({
type = "DatabaseError",
code = "CONN_REFUSED",
host = "localhost",
port = 5432,
message = "connection refused"
})Corak Pembina Ralat
Cipta fungsi kilang ralat untuk setiap jenis ralat. Kilang itu membina jadual dengan medan yang konsisten: jenis, mesej dan sebarang konteks yang berkaitan. Kaedah metam __tostring menjadikan ralat dicetak dengan kemas.
local ErrorMT = {__tostring = function(e)
return string.format("[%s] %s", e.type, e.message)
end}
local function makeError(errType, msg, data)
local e = {type=errType, message=msg}
if data then for k,v in pairs(data) do e[k]=v end end
return setmetatable(e, ErrorMT)
end
local E = {
notFound = function(name) return makeError("NOT_FOUND","not found: "..name,{name=name}) end,
badInput = function(msg,field) return makeError("BAD_INPUT",msg,{field=field}) end,
}
local ok, err = pcall(error, E.notFound("user:42"))
print(tostring(err)) -- [NOT_FOUND] not found: user:42Pemeriksaan Jenis Objek Ralat
Selepas menangkap ralat, periksa sama ada ralat itu ialah jadual dengan medan jenis yang diketahui. Ini membolehkan Anda menghantar kepada strategi pemulihan yang berbeza berdasarkan jenis ralat tanpa bergantung pada pemadanan corak rentetan.
local function handleRequest(fn)
local ok, err = pcall(fn)
if ok then return true end
if type(err) == "table" then
if err.type == "NOT_FOUND" then
print("404: " .. err.message)
elseif err.type == "BAD_INPUT" then
print("400: " .. err.message .. " (field: " .. (err.field or "?") .. ")")
else
print("500: unhandled error: " .. tostring(err))
end
else
print("500: " .. tostring(err))
end
return false
endHierarki Ralat
Simulasikan hierarki ralat dengan memeriksa medan is_a atau menggunakan jadual meta. Jenis ralat anak mewarisi medan jenis induk dan boleh dianggap sebagai induk oleh kod yang tidak memerlukan butiran khusus.
local function isError(e, errType)
if type(e) ~= "table" then return false end
return e.type == errType or e.parentType == errType
end
local function makeDbError(code, msg)
return {type="DbError:"..code, parentType="DbError", code=code, message=msg}
end
local err = makeDbError("TIMEOUT","query timed out")
print(isError(err, "DbError")) -- true
print(isError(err, "DbError:TIMEOUT")) -- true
print(isError(err, "NetworkError")) -- falseMembalut Ralat
Apabila menangkap dan menjana semula ralat, balut ralat asal untuk menambahkan konteks tanpa kehilangannya. Pembalut itu mempunyai jenisnya sendiri dan membawa ralat asal sebagai punca.
local function wrapError(msg, cause)
return {
type = "WrappedError",
message = msg,
cause = cause,
}
end
local function loadConfig(path)
local ok, err = pcall(function()
local f = assert(io.open(path,"r"))
local content = f:read("a")
f:close()
return content
end)
if not ok then
error(wrapError("failed to load config: "..path, err))
end
end
local ok2, e = pcall(loadConfig, "missing.cfg")
if not ok2 then
print(e.message)
print("Caused by:", tostring(e.cause))
endKod Ralat berbanding Jenis Ralat
Dua konvensyen yang biasa ialah: kod ralat (berangka, seperti kod status HTTP) dan rentetan jenis ralat (nama semantik). Kod ralat mudah dibandingkan secara berangka; rentetan jenis menerangkan maksudnya sendiri. Banyak sistem menggunakan kedua-duanya.
local STATUS = {OK=200, NOT_FOUND=404, SERVER_ERROR=500, BAD_REQUEST=400}
local function makeStatusError(status, msg)
return {status=status, message=msg, type="HTTPError"}
end
local function handleError(e)
if e.status == STATUS.NOT_FOUND then
print("Resource not found:", e.message)
elseif e.status >= 500 then
print("Server error:", e.message)
else
print("Error", e.status, e.message)
end
end
handleError(makeStatusError(404, "user not found"))Tindanan Ralat (Rantaian Punca)
Apabila satu ralat disebabkan oleh ralat lain, rantai kedua-duanya. Ini memberikan gambaran penuh tentang perkara yang berlaku pada setiap lapisan aplikasi. Nyahbalut rantaian itu untuk mencatat atau memaparkan keseluruhan kisah ralat.
local function unwindCause(e, depth)
depth = depth or 0
local pad = string.rep(" ", depth)
if type(e) == "table" then
print(pad .. (e.type or "Error") .. ": " .. (e.message or "?"))
if e.cause then unwindCause(e.cause, depth+1) end
else
print(pad .. tostring(e))
end
end
local inner = {type="IoError", message="permission denied"}
local outer = {type="ConfigError", message="cannot load config", cause=inner}
unwindCause(outer)
-- ConfigError: cannot load config
-- IoError: permission deniedRalat dalam Konteks Panggilan Balik
Apabila ralat berlaku di dalam panggilan balik (pengendali peristiwa, lelar), ralat itu tersebar kepada pemanggil panggilan balik. Gunakan pcall untuk menangkapnya dan melaporkannya bersama konteks tentang panggilan balik yang gagal.
local function runCallbacks(callbacks, data)
local errors = {}
for name, fn in pairs(callbacks) do
local ok, err = pcall(fn, data)
if not ok then
errors[#errors+1] = {callback=name, error=err}
end
end
return errors
end
local cbs = {
validate = function(d) assert(d.name, "name required") end,
transform = function(d) d.name = d.name:upper() end,
}
local errs = runCallbacks(cbs, {})
for _, e in ipairs(errs) do
print(e.callback, "->", e.error)
endMencetak Butiran Ralat
Pembantu yang mencetak objek ralat dengan cara yang berstruktur dan mudah dibaca — serta mengendalikan ralat rentetan dan jadual. Ini berguna pada sempadan aplikasi apabila ralat dicatat atau dipaparkan kepada pengguna.
local function printError(err, prefix)
prefix = prefix or "Error"
if type(err) ~= "table" then
print(prefix .. ": " .. tostring(err))
return
end
print(prefix .. " [" .. (err.type or "unknown") .. "]")
print(" Message: " .. (err.message or "?"))
for k, v in pairs(err) do
if k ~= "type" and k ~= "message" and k ~= "cause" then
print(" " .. k .. ": " .. tostring(v))
end
end
if err.cause then printError(err.cause, " Caused by") end
endPengesahan dengan Ralat Berstruktur
Cipta assertT (assert dengan ralat berjenis) yang menghasilkan ralat berstruktur dan bukannya rentetan biasa. Ini memudahkan pemanggil menguji jenis ralat tertentu.
local function assertT(cond, errType, msg, data)
if not cond then
local e = {type=errType, message=msg}
if data then for k,v in pairs(data) do e[k]=v end end
error(e, 2)
end
return cond
end
local function createUser(name, age)
assertT(type(name)=="string", "BAD_INPUT", "name must be string", {field="name"})
assertT(age >= 0 and age <= 150, "BAD_INPUT", "invalid age", {field="age", value=age})
return {name=name, age=age}
end
local ok, err = pcall(createUser, "Alice", -5)
if not ok then print(err.type, err.field, err.value) endSemakan Pantas
Apakah kelebihan utama menghantar jadual kepada error() berbanding rentetan?
Imbas Kembali: Ralat Berstruktur
Ringkasan:
- Hantarkan jadual kepada
error()untuk mendapatkan ralat yang berstruktur dan boleh diperiksa - Sertakan: jenis, mesej dan medan konteks yang berkaitan
- Tambahkan
__tostringuntuk keluaran yang mudah dibaca - Balut ralat untuk menambahkan konteks tanpa kehilangan punca
- Penghantaran mengikut jenis dalam pengendali: periksa
err.type, bukan corak rentetan
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 “Objek Ralat Berstruktur” percuma?
Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Lua Academy, termasuk “Objek Ralat Berstruktur”, 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 “Objek Ralat Berstruktur”?
Luluskan jadual sebagai objek ralat untuk menyampaikan jenis dan konteks. 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 4 daripada 4.
Berapa lamakah pelajaran “Objek Ralat Berstruktur” 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
- Fungsi error()
- Panggilan Terlindung dengan pcall
- xpcall dan Pengendali Mesej
- Objek Ralat Berstruktur