From c2138979f6d9837ee74405c82ca1cc67aabb720b Mon Sep 17 00:00:00 2001 From: MaddoScientisto Date: Wed, 1 May 2024 10:26:14 +0200 Subject: [PATCH] Updated error handler --- src/error_explorer.lua | 105 ++++++++++++++++++++++++++++------------- 1 file changed, 72 insertions(+), 33 deletions(-) diff --git a/src/error_explorer.lua b/src/error_explorer.lua index 77bb535..e230439 100644 --- a/src/error_explorer.lua +++ b/src/error_explorer.lua @@ -2,7 +2,7 @@ -- -- by kira -- --- version 0.0.4 +-- version 0.0.6 -- -- an interactive error screen for picotron. -- on error, shows the stack, local variables, @@ -41,6 +41,19 @@ -- -- ## 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 -- -- - also catch errors in `_init` @@ -195,9 +208,6 @@ local source_lines = {} ---- main events --------------------------------- -local W = 480 -local H = 270 - local function rebuild () -- rebuild stack frame info stack_frames = {} @@ -232,33 +242,45 @@ local function rebuild () -- rebuild variables do - local local_index = 1 - repeat - 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 + if debug.getlocal then + local local_index = 1 repeat - local name, value = debug.getupvalue (info.func, upvalue_index) + local name, value = debug.getlocal (error_thread, frame.depth, local_index) if name then - table.insert (variables, { - key = name, - value = value, - }) - upvalue_index = upvalue_index + 1 + if name ~= '(temporary)' then + table.insert (variables, { + key = name, + value = value, + }) + end + local_index = local_index + 1 end 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 @@ -328,6 +350,9 @@ local function error_update () end local function error_draw () + local W = get_display():width() + local H = get_display():height() + local prefix = use_small_font and '\014' or '' local font_height = (use_small_font and 6 or 11) local mx, my = mouse() @@ -418,9 +443,13 @@ local function error_draw () variable_count = variable_count + 1 local hovered = variable == last_hovered_variable local y_before = y - 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)) + if variable.error then + print_line (' ' .. variable.error, 8) + 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 mx >= 0 and mx < W/2 and my >= y_before and my < y then @@ -459,6 +488,10 @@ end local function reset () -- based on reset() from /system/lib/head.lua -- see that fn for info + window { + cursor = 1, + resizable = true, + } note () -- picotron segfaults if we call clip() during init if init_done then @@ -511,7 +544,12 @@ local user_update = rawget (_G, '_update') local user_draw = rawget (_G, '_draw') 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, ...) -- if there's an error in our update or draw, throw the @@ -527,8 +565,9 @@ local function call_protected (fn) -- for picotron compatibility local thread = cocreate (fn) local success, message = coresume(thread) - if costatus (thread) ~= 'dead' then - call_error_event (on_error, thread, 'setup_error_display.lua: _update and _draw shouldn\'t yield') + while costatus (thread) ~= 'dead' do + yield () + success, message = coresume (thread) end if not success then call_error_event (on_error, thread, message)