From 90ce2bb1a52ed416a2506f0ae96184ba442a00c6 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Tue, 12 May 2020 21:25:37 -0600 Subject: [PATCH] Improved error messages --- sys/apps/shell.lua | 6 ++--- sys/init/7.multishell.lua | 31 ++++++++++++++++++++------ sys/kernel.lua | 6 ++--- sys/modules/opus/trace.lua | 45 +++++++++++++++++++------------------- 4 files changed, 53 insertions(+), 35 deletions(-) diff --git a/sys/apps/shell.lua b/sys/apps/shell.lua index 92cf23d..52dcc33 100644 --- a/sys/apps/shell.lua +++ b/sys/apps/shell.lua @@ -52,8 +52,8 @@ local function run(...) loadFn = loadfile end - local fn, err = loadFn(path, env) - if not fn then + local bill, err = loadFn(path, env) + if not bill then error(err, -1) end @@ -68,7 +68,7 @@ local function run(...) } env[ "arg" ] = { [0] = path, table.unpack(args) } - local r = { fn(table.unpack(args)) } + local r = { bill(table.unpack(args)) } tProgramStack[#tProgramStack] = nil diff --git a/sys/init/7.multishell.lua b/sys/init/7.multishell.lua index 3d2f0ba..3930eae 100644 --- a/sys/init/7.multishell.lua +++ b/sys/init/7.multishell.lua @@ -106,17 +106,34 @@ function multishell.openTab(env, tab) end tab.title = tab.title or 'untitled' tab.window = tab.window or window.create(parentTerm, 1, 2, w, h - 1, false) - tab.onExit = tab.onExit or function(self, result, err) - if not result and err and err ~= 'Terminated' or (err and err ~= 0) then - self.terminal.setBackgroundColor(colors.black) + tab.onExit = tab.onExit or function(self, result, err, stack) + if not result and err and err ~= 'Terminated' then + self.terminal.setTextColor(colors.white) + self.terminal.setCursorBlink(false) + print('\nThe program terminated with an error.\n') if tonumber(err) then - self.terminal.setTextColor(colors.orange) - print('Process exited with error code: ' .. err) + printError('Process exited with error code: ' .. err) elseif err then printError(tostring(err)) end - self.terminal.setTextColor(colors.white) - print('\nPress enter to close') + if type(stack) == 'table' and #stack > 0 then + local _, cy = self.terminal.getCursorPos() + local _, th = self.terminal.getSize() + self.terminal.setTextColor(colors.white) + if cy < th - 4 then + print('\nstack traceback:') + for _, v in ipairs(stack or { }) do + _, cy = self.terminal.getCursorPos() + if cy > th - 3 then + print(' ...') + break + end + print(v) + end + end + end + self.terminal.setTextColor(parentTerm.isColor() and colors.yellow or colors.white) + _G.write('\nPress enter to close') self.isDead = true self.hidden = false redrawMenu() diff --git a/sys/kernel.lua b/sys/kernel.lua index 5f86bd4..446d227 100644 --- a/sys/kernel.lua +++ b/sys/kernel.lua @@ -110,7 +110,7 @@ end function Routine:run() self.co = self.co or coroutine.create(function() - local result, err, fn + local result, err, fn, stack if self.fn then fn = self.fn @@ -122,12 +122,12 @@ function Routine:run() end if fn then - result, err = trace(fn, table.unpack(self.args or { } )) + result, err, stack = trace(fn, table.unpack(self.args or { } )) else err = err or 'kernel: invalid routine' end - pcall(self.onExit, self, result, err) + pcall(self.onExit, self, result, err, stack) self:cleanup() if not result then diff --git a/sys/modules/opus/trace.lua b/sys/modules/opus/trace.lua index bb12fde..d003f48 100644 --- a/sys/modules/opus/trace.lua +++ b/sys/modules/opus/trace.lua @@ -32,15 +32,28 @@ local function traceback(x) end end -local function trim_traceback(target) - local t = { } +local function trim_traceback(stack) + local trace = { } local filters = { "%[C%]: in function 'xpcall'", "(...tail calls...)", "xpcall: $", "trace.lua:%d+:", + "stack traceback:", } + for line in stack:gmatch("([^\n]*)\n?") do table.insert(trace, line) end + + local err = { } + while true do + local line = table.remove(trace, 1) + if not line or line == 'stack traceback:' then + break + end + table.insert(err, line) + end + err = table.concat(err, '\n') + local function matchesFilter(line) for _, filter in pairs(filters) do if line:match(filter) then @@ -49,13 +62,15 @@ local function trim_traceback(target) end end - for line in target:gmatch("([^\n]*)\n?") do + local t = { } + for _, line in pairs(trace) do if not matchesFilter(line) then + line = line:gsub("in function", "in") table.insert(t, line) end end - return t + return err, t end return function (fn, ...) @@ -66,29 +81,15 @@ return function (fn, ...) return fn(table.unpack(args)) end, traceback)) - local ok, err = res[1], res[2] - - if not ok and err ~= nil then - local trace = trim_traceback(err) - - err = { } - while true do - local line = table.remove(trace, 1) - if not line or line == 'stack traceback:' then - break - end - table.insert(err, line) - end - err = table.concat(err, '\n') + if not res[1] and res[2] ~= nil then + local err, trace = trim_traceback(res[2]) _G._syslog('\n' .. err .. '\n' .. 'stack traceback:') for _, v in ipairs(trace) do - if v ~= 'stack traceback:' then - _G._syslog(v:gsub("in function", "in")) - end + _G._syslog(v) end - return ok, err + return res[1], err, trace end return table.unpack(res, 1, res.n)