Lua Xpcall Handlers
xpcall is a function that runs another function and calls a handler with the error value when that function fails. The handler turns a raw error into a result the program can use.
A handler turns a raw error into a clean message
The risky function fails with a plain message: error with level 0 reports no position. The handler adds a readable prefix.
local function risky()
error("bad input", 0)
end
local function handler(err)
return "problem: " .. err
end
local ok, message = xpcall(risky, handler)
print(ok, message)The handler receives the error value
The handler takes the error as its argument. It reports the type and the value it received.
local function risky()
error("missing file", 0)
end
local function handler(err)
return type(err) .. ": " .. err
end
local ok, message = xpcall(risky, handler)
print(ok, message)On success the handler never runs
The handler would count a call if it ran. The count stays zero on success.
local handled = 0
local function handler(err)
handled = handled + 1
return "handled"
end
local ok, value = xpcall(function() return 42 end, handler)
print(ok, value, handled)Example
local function handler(err)
return "clean: " .. err
end
local function run(job)
local ok, result = xpcall(job, handler)
return ok, result
end
local ok1, value1 = run(function() return 7 * 6 end)
local ok2, value2 = run(function() error("too big", 0) end)
print(ok1, value1)
print(ok2, value2)Key points
- Handler: the handler is a function that receives the error value when the called function fails.
- Return on failure: xpcall returns false followed by the value the handler returns.
- Return on success: xpcall returns true followed by the called function's results, and the handler never runs.
- Clean message: a handler can build a short readable message from a raw error value.
- Level 0: error with level 0 reports the bare message with no position.
- Handler result: the program receives the handler's return value, not the original error.
In this example, a run helper wraps each job in xpcall with the same handler. The good job returns true and 42 with the handler unused, and the bad job returns false with the handler's clean message.
Note
xpcall needs a handler function, while pcall returns the error value directly.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What does xpcall return when the function fails and the handler returns "fixed"?