Skip to content
Error Handling
step 1/5

Reading — step 1 of 5

Learn

~1 min readCoroutines and Errors

Lua throws errors by calling error(msg). To catch them, use pcall ("protected call"):

local ok, err = pcall(function()
    error("something broke")
end)
print(ok, err)        -- false   input:2: something broke

pcall returns (true, ...) if the function succeeds (with all return values), or (false, error) if it throws.

Catching specific errors — Lua's error "type" is whatever you pass to error:

local function divide(a, b)
    if b == 0 then
        error({code = "div_zero", message = "divide by zero"})
    end
    return a / b
end

local ok, err = pcall(divide, 10, 0)
if not ok then
    if type(err) == "table" and err.code == "div_zero" then
        print("caught division by zero")
    else
        print("unknown error: " .. tostring(err))
    end
end

Lua doesn't have built-in exception classes. Convention is to throw strings (for messages) or tables (for structured errors).

xpcall — like pcall but with a custom error handler that runs in the error's stack frame (so it can capture stack info):

xpcall(
    function() error("oops") end,
    function(err) return debug.traceback(err) end
)

assert(condition, msg) — shortcut for "throw if falsy":

assert(file, "file is required")
assert(n > 0, "n must be positive")

Lua errors propagate up through function calls until caught (or terminate the program). Most idiomatic Lua code uses errors only for truly unexpected failures and returns (value, error) tuples for expected errors:

local value, err = io.open("missing.txt")
if not value then return nil, err end

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…