lovr.errhand
EditThe lovr.errhand
callback is run whenever an error occurs. It receives a parameter containing the error message. It should return a handler function that will run in a loop to render the error screen.
This handler function is of the same type as the one returned by lovr.run
and has the same requirements (such as pumping events). If an error occurs while this handler is running, the program will terminate immediately -- lovr.errhand
will not be given a second chance. Errors which occur in the error handler or in the handler it returns may not be cleanly reported, so be careful.
A default error handler is supplied that renders the error message as text to the headset and to the window.
function lovr.errhand(message)
-- your code here
end
Arguments
Name | Type | Description |
message | string | The error message. |
Returns
Name | Type | Description |
handler | function | The error handler function. It should return nil to continue running, "restart" to restart the app, or a number representing an exit status. |
Example
The default error handler.
function lovr.errhand(message)
local function formatTraceback(s)
return s:gsub('\n[^\n]+$', ''):gsub('\t', ''):gsub('stack traceback:', '\nStack:\n')
end
message = 'Error:\n\n' .. tostring(message) .. formatTraceback(debug.traceback('', 4))
print(message)
if not lovr.graphics or not lovr.graphics.isInitialized() then
return function() return 1 end
end
if lovr.audio then lovr.audio.stop() end
if not lovr.headset or lovr.headset.getPassthrough() == 'opaque' then
lovr.graphics.setBackgroundColor(.11, .10, .14)
else
lovr.graphics.setBackgroundColor(0, 0, 0, 0)
end
local font = lovr.graphics.getDefaultFont()
return function()
lovr.system.pollEvents()
for name, a in lovr.event.poll() do
if name == 'quit' then return a or 1
elseif name == 'restart' then return 'restart', lovr.restart and lovr.restart()
elseif name == 'keypressed' and a == 'f5' then lovr.event.restart()
elseif name == 'keypressed' and a == 'escape' then lovr.event.quit() end
end
if lovr.headset and lovr.headset.getDriver() ~= 'simulator' then
lovr.headset.update()
local pass = lovr.headset.getPass()
if pass then
font:setPixelDensity()
local scale = .35
local font = lovr.graphics.getDefaultFont()
local wrap = .7 * font:getPixelDensity()
local lines = font:getLines(message, wrap)
local width = math.min(font:getWidth(message), wrap) * scale
local height = .8 + #lines * font:getHeight() * scale
local x = -width / 2
local y = math.min(height / 2, 10)
local z = -10
pass:setColor(.95, .95, .95)
pass:text(message, x, y, z, scale, 0, 0, 0, 0, wrap, 'left', 'top')
lovr.graphics.submit(pass)
lovr.headset.submit()
end
end
if lovr.system.isWindowOpen() then
local pass = lovr.graphics.getWindowPass()
if pass then
local w, h = lovr.system.getWindowDimensions()
pass:setProjection(1, lovr.math.mat4():orthographic(0, w, 0, h, -1, 1))
font:setPixelDensity(1)
local scale = .6
local wrap = w * .8 / scale
local width = math.min(font:getWidth(message), wrap) * scale
local x = w / 2 - width / 2
pass:setColor(.95, .95, .95)
pass:text(message, x, h / 2, 0, scale, 0, 0, 0, 0, wrap, 'left', 'middle')
lovr.graphics.submit(pass)
lovr.graphics.present()
end
end
lovr.math.drain()
end
end