ฟังก์ชัน error()
สร้างข้อผิดพลาดด้วย error() และทำความเข้าใจระดับกับข้อความของข้อผิดพลาด
ฟังก์ชัน error() เป็นบทเรียน Lua Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Lua Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน
การยกข้อผิดพลาด
error(message, level) ยกข้อผิดพลาดของ Lua การทำงานจะหยุดลง และข้อผิดพลาดจะถูกส่งย้อนขึ้นไปตามลำดับการเรียกฟังก์ชันจนกว่าจะถูกจับด้วย pcall หรือ xpcall หรือจนกว่าโปรแกรมจะจบการทำงาน ข้อความสามารถเป็นค่าใดก็ได้ เช่น สตริง ตาราง หรือตัวเลข
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ระดับข้อผิดพลาด
อาร์กิวเมนต์ตัวที่สองของ error() กำหนดตำแหน่งที่รายงานข้อผิดพลาด ระดับ 1 (ค่าเริ่มต้น) ชี้ไปยังจุดเรียก error() เอง ระดับ 2 ชี้ไปยังผู้เรียก ระดับ 0 จะไม่เพิ่มข้อมูลตำแหน่ง ใช้ระดับ 2 ในฟังก์ชันของไลบรารีเพื่อชี้ให้เห็นโค้ดของผู้ใช้
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ข้อผิดพลาดที่มีออบเจ็กต์ตาราง
การส่งตารางเป็นค่าข้อผิดพลาดทำให้ผู้เรียกตรวจสอบข้อมูลข้อผิดพลาดที่มีโครงสร้างได้ เช่น รหัสข้อผิดพลาด ข้อความ และบริบท วิธีนี้ให้ข้อมูลมากกว่าสตริงธรรมดาและเปิดทางให้จัดการข้อผิดพลาดด้วยโปรแกรม
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)
endassert() ในรูปแบบย่อ
assert(v, msg) มีความหมายเทียบเท่ากับ if not v then error(msg, 2) end; return v, ... เหมาะสำหรับตรวจสอบเงื่อนไขเบื้องต้น หาก v เป็นค่าที่ถือว่าเป็นจริง assert จะคืนค่าอาร์กิวเมนต์ทั้งหมด (มีประโยชน์สำหรับการเรียกต่อเนื่อง)
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 stringerror() กับ return nil,err
มีแบบแผนสองรูปแบบสำหรับสื่อว่าการทำงานล้มเหลว: error() (รูปแบบข้อยกเว้น) หรือ return nil, msg (รูปแบบฟังก์ชัน) ใช้ error() สำหรับเงื่อนไขที่ไม่คาดคิดอย่างแท้จริง (ข้อผิดพลาดในการเขียนโปรแกรมหรือการละเมิดข้อตกลง) ใช้ nil, msg สำหรับความล้มเหลวที่คาดการณ์ได้ (ไม่พบไฟล์หรือหมดเวลาการเชื่อมต่อเครือข่าย)
-- 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ข้อผิดพลาดในเมธาเมธอด
สามารถยกข้อผิดพลาดภายในเมธาเมธอดได้ หากเมธาเมธอดเกิดข้อผิดพลาด ข้อผิดพลาดนั้นจะถูกส่งต่อไปยังโค้ดที่เรียกใช้การดำเนินการดังกล่าว (เช่น นิพจน์เลขคณิต) โปรดตรวจสอบอินพุตที่ไม่ถูกต้องในเมธาเมธอดเสมอ
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)ประเภทข้อผิดพลาดแบบกำหนดเอง
สร้างตัวช่วยสำหรับสร้างออบเจ็กต์ข้อผิดพลาดที่มีชนิดกำกับไว้ โดยให้มีป้ายระบุชนิดเพื่อให้ผู้เรียกแยกแยะข้อผิดพลาดแต่ละประเภทและจัดการได้อย่างเหมาะสม
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การส่งต่อข้อผิดพลาด
เมื่อฟังก์ชันหนึ่งเรียกใช้ฟังก์ชันอื่นแล้วเกิดข้อผิดพลาด ข้อผิดพลาดนั้นจะถูกส่งต่อขึ้นไปตามลำดับการเรียกโดยอัตโนมัติ คุณไม่จำเป็นต้องโยนข้อผิดพลาดซ้ำ เพียงอย่าดักจับไว้ ควรดักจับข้อผิดพลาดเฉพาะในระดับที่สามารถจัดการหรือรายงานได้อย่างมีความหมาย
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ร่องรอยการเรียกด้วย debug.traceback
error() แบบธรรมดาจะให้บริบทเพียงหนึ่งบรรทัด หากต้องการร่องรอยการเรียกทั้งหมด ให้ใช้ debug.traceback(msg) เป็นค่าข้อผิดพลาด โดยทั่วไปจะทำเช่นนี้ในตัวจัดการของ 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การโยนข้อผิดพลาดซ้ำ
บางครั้งคุณดักจับข้อผิดพลาดเพื่อเพิ่มบริบท แล้วจึงโยนข้อผิดพลาดนั้นซ้ำ ให้ใช้ error(err, 0) (ระดับ 0) เมื่อต้องการโยนข้อผิดพลาดชนิดสตริงซ้ำ เพื่อไม่ให้มีคำนำหน้าตำแหน่งเพิ่มในข้อความที่จัดรูปแบบไว้แล้ว
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)ตรวจสอบอย่างรวดเร็ว
ระดับ 2 ใน error("msg", 2) หมายถึงอะไร
ทบทวน: error()
สรุป:
error(msg, level)— ยกข้อผิดพลาดขึ้นมา โดยระดับ 2 จะระบุว่าผู้เรียกเป็นต้นเหตุ- ใช้ตารางสำหรับข้อผิดพลาดแบบมีโครงสร้าง ซึ่งประกอบด้วยชนิดและบริบท
assert(v, msg)— การตรวจสอบเงื่อนไขเบื้องต้นตามรูปแบบที่นิยมใช้- ใช้
error()สำหรับข้อผิดพลาดในโปรแกรม ส่วนความล้มเหลวที่คาดหมายได้ให้คืนค่า nil+err - โยนซ้ำด้วย
error(err, 0)เพื่อคงรูปแบบข้อความเดิม
คำถามที่พบบ่อย
บทเรียน “ฟังก์ชัน error()” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ฟังก์ชัน error()” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Lua Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ฟังก์ชัน error()”
สร้างข้อผิดพลาดด้วย error() และทำความเข้าใจระดับกับข้อความของข้อผิดพลาด คุณปฏิบัติ Lua Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Lua Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Lua Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “ฟังก์ชัน error()” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Lua Academy นี้ได้ไหม
ได้ บทเรียน Lua Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ฟังก์ชัน error()
- การเรียกใช้แบบป้องกันด้วย pcall
- xpcall และตัวจัดการข้อความ
- ออบเจกต์ข้อผิดพลาดแบบมีโครงสร้าง