Lua Error Handling Guide — Protected Calls and Exception Patterns
In this tutorial, you will learn about Lua Error Handling Guide. We cover key concepts, practical examples, and best practices to help you master this topic.
Lua error handling centers on pcall (protected call) which executes a function in protected mode and returns success status plus results -- with xpcall adding a message handler for custom error processing before the stack unwinds.
Basic pcall
local function divide(a, b)
if b == 0 then
error("Division by zero")
end
return a / b
end
local ok, result = pcall(divide, 10, 0)
if ok then
print("Result:", result)
else
print("Error:", result) --> Error: Division by zero
end
xpcall with Error Handler
local function errorHandler(err)
print("Custom handler:", err)
print(debug.traceback())
return "Wrapped: " .. err
end
local ok, result = xpcall(function()
error("Something broke")
end, errorHandler)
if not ok then
print("Final:", result)
end
Raising Errors
-- error(message) -- raises an error
-- error(message, level) -- level 1 = caller, level 2 = caller's caller
function validatePositive(n)
if type(n) ~= "number" then
error("Expected number, got " .. type(n), 2)
end
if n <= 0 then
error("Must be positive", 2)
end
end
Assert Pattern
local function loadConfig(filename)
local f = assert(io.open(filename, "r"), "Cannot open " .. filename)
local content = assert(f:read("*all"), "Cannot read " .. filename)
f:close()
return content
end
-- assert returns the value on success, or raises on nil/false
local value = assert(tonumber("42"), "Not a number")
Try-Catch Pattern
local function try(func, catch)
local ok, result = pcall(func)
if not ok and catch then
catch(result)
end
return ok, result
end
try(function()
error("runtime error")
end, function(err)
print("Caught:", err)
end)
Common Mistakes
1. Catching and ignoring errors
Always log or handle errors. Silent failures make debugging impossible.
2. Using error for control flow
Use error only for exceptional situations. Use return values for expected failure cases.
3. Not providing enough context in error messages
Include function name and relevant values: error("validateAge: invalid age " .. tostring(age)).
Practice Questions
1. What is the difference between pcall and xpcall? xpcall accepts a message handler function that processes the error before the stack unwinds.
2. How does error's second argument work? The level argument controls where the error message points. Level 1 (default) points to the function calling error. Level 2 points to the caller's caller.
3. What does assert do? assert(condition, message) returns condition if truthy, or raises an error with the message if falsy.
FAQ
{{< faq question="Can I catch a Lua error in C code?" >}} Yes. The Lua C API uses lua_pcall which mirrors pcall. The C code can check the return status and handle errors from Lua. {{< /faq >}}
{{< faq question="How do I get a stack trace from an error?" >}}
Use xpcall with debug.traceback as the message handler: xpcall(func, debug.traceback).
{{< /faq >}}
{{< faq question="What types can be thrown with error?" >}} Any Lua value: strings, tables, or userdata. Strings are the convention. Use tables for structured error data. {{< /faq >}}
What's Next
Now learn about advanced OOP patterns in Lua.
| Topic | Description | Link |
|---|---|---|
| OOP Advanced | Inheritance, mixins, patterns | {{< ref "24-oop-advanced" >}} |
| Weak Tables | Weak references and caches | {{< ref "25-weak-tables" >}} |
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro