Updated error handler

This commit is contained in:
MaddoScientisto 2024-05-01 10:26:14 +02:00
commit c2138979f6

View file

@ -2,7 +2,7 @@
-- --
-- by kira -- by kira
-- --
-- version 0.0.4 -- version 0.0.6
-- --
-- an interactive error screen for picotron. -- an interactive error screen for picotron.
-- on error, shows the stack, local variables, -- on error, shows the stack, local variables,
@ -41,6 +41,19 @@
-- --
-- ## version history -- ## version history
-- --
-- version 0.0.6
-- - on error:
-- - show cursor
-- - make window resizable
-- - automatically adjust layout to window size
-- - support yielding (since fetch sometimes yields)
--
-- version 0.0.5
--
-- - future proofing: gracefully handle when
-- various parts of the `debug` module aren't
-- available
--
-- version 0.0.4 -- version 0.0.4
-- --
-- - also catch errors in `_init` -- - also catch errors in `_init`
@ -195,9 +208,6 @@ local source_lines = {}
---- main events --------------------------------- ---- main events ---------------------------------
local W = 480
local H = 270
local function rebuild () local function rebuild ()
-- rebuild stack frame info -- rebuild stack frame info
stack_frames = {} stack_frames = {}
@ -232,33 +242,45 @@ local function rebuild ()
-- rebuild variables -- rebuild variables
do do
local local_index = 1 if debug.getlocal then
repeat local local_index = 1
local name, value = debug.getlocal (error_thread, frame.depth, local_index)
if name then
if name ~= '(temporary)' then
table.insert (variables, {
key = name,
value = value,
})
end
local_index = local_index + 1
end
until not name
local info = debug.getinfo (error_thread, frame.depth)
if info and info.func then
local upvalue_index = 1
repeat repeat
local name, value = debug.getupvalue (info.func, upvalue_index) local name, value = debug.getlocal (error_thread, frame.depth, local_index)
if name then if name then
table.insert (variables, { if name ~= '(temporary)' then
key = name, table.insert (variables, {
value = value, key = name,
}) value = value,
upvalue_index = upvalue_index + 1 })
end
local_index = local_index + 1
end end
until not name until not name
else
table.insert (variables, {
error = 'no debug.getlocal, can\'t show locals'
})
end
if debug.getupvalue then
local info = debug.getinfo (error_thread, frame.depth)
if info and info.func then
local upvalue_index = 1
repeat
local name, value = debug.getupvalue (info.func, upvalue_index)
if name then
table.insert (variables, {
key = name,
value = value,
})
upvalue_index = upvalue_index + 1
end
until not name
end
else
table.insert (variables, {
error = 'no debug.getupvalue, can\'t show upvalues'
})
end end
end end
@ -328,6 +350,9 @@ local function error_update ()
end end
local function error_draw () local function error_draw ()
local W = get_display():width()
local H = get_display():height()
local prefix = use_small_font and '\014' or '' local prefix = use_small_font and '\014' or ''
local font_height = (use_small_font and 6 or 11) local font_height = (use_small_font and 6 or 11)
local mx, my = mouse() local mx, my = mouse()
@ -418,9 +443,13 @@ local function error_draw ()
variable_count = variable_count + 1 variable_count = variable_count + 1
local hovered = variable == last_hovered_variable local hovered = variable == last_hovered_variable
local y_before = y local y_before = y
print_horizontal (indent .. variable.key, hovered and 7 or 6) if variable.error then
print_horizontal (': ', variable == last_hovered_variable and 7 or 5) print_line (' ' .. variable.error, 8)
print_line (safe_tostring(variable.value)) else
print_horizontal (indent .. variable.key, hovered and 7 or 6)
print_horizontal (': ', variable == last_hovered_variable and 7 or 5)
print_line (safe_tostring(variable.value))
end
if over_section and type (variable.value) == 'table' then if over_section and type (variable.value) == 'table' then
if mx >= 0 and mx < W/2 and my >= y_before and my < y then if mx >= 0 and mx < W/2 and my >= y_before and my < y then
@ -459,6 +488,10 @@ end
local function reset () local function reset ()
-- based on reset() from /system/lib/head.lua -- based on reset() from /system/lib/head.lua
-- see that fn for info -- see that fn for info
window {
cursor = 1,
resizable = true,
}
note () note ()
-- picotron segfaults if we call clip() during init -- picotron segfaults if we call clip() during init
if init_done then if init_done then
@ -511,7 +544,12 @@ local user_update = rawget (_G, '_update')
local user_draw = rawget (_G, '_draw') local user_draw = rawget (_G, '_draw')
assert (user_draw and user_update, assert (user_draw and user_update,
'please include install_error_handler after defining both _update and _draw') 'please include error_explorer after defining both _update and _draw')
if not rawget (_G, 'debug') or not debug.traceback or not debug.getinfo then
printh 'error explorer: debug module not available, error explorer will be disabled'
return
end
local function call_error_event (fn, ...) local function call_error_event (fn, ...)
-- if there's an error in our update or draw, throw the -- if there's an error in our update or draw, throw the
@ -527,8 +565,9 @@ local function call_protected (fn)
-- for picotron compatibility -- for picotron compatibility
local thread = cocreate (fn) local thread = cocreate (fn)
local success, message = coresume(thread) local success, message = coresume(thread)
if costatus (thread) ~= 'dead' then while costatus (thread) ~= 'dead' do
call_error_event (on_error, thread, 'setup_error_display.lua: _update and _draw shouldn\'t yield') yield ()
success, message = coresume (thread)
end end
if not success then if not success then
call_error_event (on_error, thread, message) call_error_event (on_error, thread, message)