-
-
Notifications
You must be signed in to change notification settings - Fork 13
/
errorhandler.lua
141 lines (117 loc) · 3.31 KB
/
errorhandler.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
-- Slightly modified error handler, based on LOVE 11.0 error handler
-- Part of Live Simulator: 2
local love = require("love")
local color = require("color")
local log = require("logging")
local Util = require("util")
local PostExit = require("post_exit")
local utf8 = require("utf8")
local function error_printer(msg, layer)
log.error("errhand", (debug.traceback("Error: " .. tostring(msg), 1+(layer or 1)):gsub("\n[^\n]+$", "")))
end
function love.errorhandler(msg)
PostExit.exit()
msg = tostring(msg)
error_printer(msg, 2)
if not love.window or not love.graphics or not love.event then
return
end
if not love.graphics.isCreated() or not love.window.isOpen() then
return
end
-- Reset state.
if love.mouse then
love.mouse.setVisible(true)
love.mouse.setGrabbed(false)
love.mouse.setRelativeMode(false)
if Util.isCursorSupported() then
love.mouse.setCursor()
end
end
if love.joystick then
-- Stop all joystick vibrations.
for _,v in ipairs(love.joystick.getJoysticks()) do
v:setVibration()
end
end
if love.audio then love.audio.stop() end
love.graphics.reset()
love.graphics.setNewFont(14)
love.graphics.setColor(color.white)
local trace = debug.traceback()
love.graphics.origin()
local sanitizedmsg = {}
for char in msg:gmatch(utf8.charpattern) do
table.insert(sanitizedmsg, char)
end
sanitizedmsg = table.concat(sanitizedmsg)
local err = {}
table.insert(err, "Error\n")
table.insert(err, sanitizedmsg)
if #sanitizedmsg ~= #msg then
table.insert(err, "Invalid UTF-8 string in error message.")
end
table.insert(err, "\n")
for l in trace:gmatch("(.-)\n") do
if not l:match("boot.lua") then
l = l:gsub("stack traceback:", "Traceback\n")
table.insert(err, l)
end
end
local p = table.concat(err, "\n")
p = p:gsub("\t", "")
p = p:gsub("%[string \"(.-)\"%]", "%1")
local function draw()
local pos = 70
love.graphics.printf(p, pos, pos, love.graphics.getWidth() - pos)
love.graphics.present()
love.graphics.clear(color.hex599DDC)
end
local fullErrorText = p
local function copyToClipboard()
if not love.system then return end
love.system.setClipboardText(fullErrorText)
p = p .. "\nCopied to clipboard!"
--return draw()
end
if love.system then
p = p .. "\n\nPress Ctrl+C or tap to copy this error"
end
local step = function()
love.event.pump()
for e, a in love.event.poll() do
if e == "quit" then
return 1
elseif e == "keypressed" and a == "escape" then
return 1
elseif e == "keypressed" and a == "c" and love.keyboard.isDown("lctrl", "rctrl") then
copyToClipboard()
elseif e == "touchpressed" then
local name = love.window.getTitle()
if #name == 0 or name == "Untitled" then name = "Game" end
local buttons = {"OK", "Cancel"}
if love.system then
buttons[3] = "Copy to clipboard"
end
local pressed = love.window.showMessageBox("Quit "..name.."?", "", buttons)
if pressed == 1 then
return 1
elseif pressed == 3 then
copyToClipboard()
end
end
end
draw()
end
if love._version >= "11.0" then
return step
else
while true do
local value = step()
if value ~= nil then
return value
end
end
end
end
love.errhand = love.errorhandler