More improvements to error reporting.
This commit is contained in:
parent
8806d7639e
commit
21e3a7b375
65
nomsu.lua
65
nomsu.lua
@ -1501,7 +1501,7 @@ OPTIONS
|
|||||||
break
|
break
|
||||||
end
|
end
|
||||||
level = level + 1
|
level = level + 1
|
||||||
local name = calling_fn.name
|
local name = calling_fn.name and "function '" .. tostring(calling_fn.name) .. "'" or nil
|
||||||
if calling_fn.linedefined == 0 then
|
if calling_fn.linedefined == 0 then
|
||||||
name = "main chunk"
|
name = "main chunk"
|
||||||
end
|
end
|
||||||
@ -1527,20 +1527,17 @@ OPTIONS
|
|||||||
assert(filename)
|
assert(filename)
|
||||||
local file = FILE_CACHE[filename]:sub(tonumber(start), tonumber(stop))
|
local file = FILE_CACHE[filename]:sub(tonumber(start), tonumber(stop))
|
||||||
local err_line = get_line(file, calling_fn.currentline):sub(1, -2)
|
local err_line = get_line(file, calling_fn.currentline):sub(1, -2)
|
||||||
local offending_statement = colored.red(err_line)
|
local offending_statement = colored.bright(colored.red(err_line:match("^[ ]*(.*)")))
|
||||||
line = colored.yellow(tostring(filename) .. ":" .. tostring(calling_fn.currentline) .. "\n" .. tostring(offending_statement))
|
|
||||||
do
|
do
|
||||||
local arg_orders = nomsu.environment.ARG_ORDERS[calling_fn.func]
|
local arg_orders = nomsu.environment.ARG_ORDERS[calling_fn.func]
|
||||||
if arg_orders then
|
if arg_orders then
|
||||||
name = colored.bright(colored.yellow(next(arg_orders)))
|
name = "action '" .. tostring(next(arg_orders)) .. "'"
|
||||||
else
|
else
|
||||||
name = colored.bright(colored.yellow("main chunk"))
|
name = "main chunk"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
line = colored.yellow(tostring(filename) .. ":" .. tostring(calling_fn.currentline) .. " in " .. tostring(name) .. "\n " .. tostring(offending_statement))
|
||||||
else
|
else
|
||||||
if calling_fn.istailcall and not name then
|
|
||||||
name = "<tail call>"
|
|
||||||
end
|
|
||||||
local file
|
local file
|
||||||
ok, file = pcall(function()
|
ok, file = pcall(function()
|
||||||
return FILE_CACHE[calling_fn.short_src]
|
return FILE_CACHE[calling_fn.short_src]
|
||||||
@ -1549,20 +1546,40 @@ OPTIONS
|
|||||||
file = nil
|
file = nil
|
||||||
end
|
end
|
||||||
local line_num
|
local line_num
|
||||||
if name == nil and debug.getinfo(level + 1) then
|
if name == nil then
|
||||||
local i = 1
|
local search_level = level
|
||||||
while true do
|
local _info = debug.getinfo(search_level)
|
||||||
local varname, val = debug.getlocal(level + 1, i)
|
while _info and (_info.func == pcall or _info.func == xpcall) do
|
||||||
|
search_level = search_level + 1
|
||||||
|
_info = debug.getinfo(search_level)
|
||||||
|
end
|
||||||
|
if _info then
|
||||||
|
for i = 1, 999 do
|
||||||
|
local varname, val = debug.getlocal(search_level, i)
|
||||||
if not varname then
|
if not varname then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
if val == calling_fn.func then
|
if val == calling_fn.func then
|
||||||
name = varname
|
name = "local '" .. tostring(varname) .. "'"
|
||||||
if not varname:match("%(") then
|
if not varname:match("%(") then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
i = i + 1
|
end
|
||||||
|
if not (name) then
|
||||||
|
for i = 1, _info.nups do
|
||||||
|
local varname, val = debug.getupvalue(_info.func, i)
|
||||||
|
if not varname then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if val == calling_fn.func then
|
||||||
|
name = "upvalue '" .. tostring(varname) .. "'"
|
||||||
|
if not varname:match("%(") then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if file and calling_fn.short_src:match(".moon$") and LINE_TABLES[file] then
|
if file and calling_fn.short_src:match(".moon$") and LINE_TABLES[file] then
|
||||||
@ -1571,22 +1588,26 @@ OPTIONS
|
|||||||
for _ in file:sub(1, char):gmatch("\n") do
|
for _ in file:sub(1, char):gmatch("\n") do
|
||||||
line_num = line_num + 1
|
line_num = line_num + 1
|
||||||
end
|
end
|
||||||
line = colored.cyan(tostring(calling_fn.short_src) .. ":" .. tostring(line_num))
|
line = colored.cyan(tostring(calling_fn.short_src) .. ":" .. tostring(line_num) .. " in " .. tostring(name or '?'))
|
||||||
name = colored.bright(colored.cyan(name or "???"))
|
|
||||||
else
|
else
|
||||||
line_num = calling_fn.currentline
|
line_num = calling_fn.currentline
|
||||||
line = colored.blue(tostring(calling_fn.short_src) .. ":" .. tostring(calling_fn.currentline))
|
if calling_fn.short_src == '[C]' then
|
||||||
name = colored.bright(colored.blue(name or "???"))
|
line = colored.green(tostring(calling_fn.short_src) .. " in " .. tostring(name or '?'))
|
||||||
|
else
|
||||||
|
line = colored.blue(tostring(calling_fn.short_src) .. ":" .. tostring(calling_fn.currentline) .. " in " .. tostring(name or '?'))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if file then
|
if file then
|
||||||
local err_line = get_line(file, line_num):sub(1, -2)
|
local err_line = get_line(file, line_num):sub(1, -2)
|
||||||
local offending_statement = colored.red(err_line)
|
local offending_statement = colored.bright(colored.red(err_line:match("^[ ]*(.*)$")))
|
||||||
line = line .. ("\n " .. offending_statement)
|
line = line .. ("\n " .. offending_statement)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local _from = colored.dim(colored.white("|"))
|
io.stderr:write(" " .. tostring(line) .. "\n")
|
||||||
io.stderr:write(("%32s %s %s\n"):format(name, _from, line))
|
if calling_fn.istailcall then
|
||||||
|
io.stderr:write(" " .. tostring(colored.dim(colored.white(" (...tail calls...)"))) .. "\n")
|
||||||
|
end
|
||||||
_continue_0 = true
|
_continue_0 = true
|
||||||
until true
|
until true
|
||||||
if not _continue_0 then
|
if not _continue_0 then
|
||||||
@ -1727,7 +1748,7 @@ OPTIONS
|
|||||||
do
|
do
|
||||||
local ldt
|
local ldt
|
||||||
ok, ldt = pcall(require, 'ldt')
|
ok, ldt = pcall(require, 'ldt')
|
||||||
if ok then
|
if ok and false then
|
||||||
ldt.guard(run)
|
ldt.guard(run)
|
||||||
else
|
else
|
||||||
xpcall(run, err_hand)
|
xpcall(run, err_hand)
|
||||||
|
55
nomsu.moon
55
nomsu.moon
@ -1056,7 +1056,7 @@ OPTIONS
|
|||||||
if not calling_fn then break
|
if not calling_fn then break
|
||||||
if calling_fn.func == run then break
|
if calling_fn.func == run then break
|
||||||
level += 1
|
level += 1
|
||||||
name = calling_fn.name
|
name = calling_fn.name and "function '#{calling_fn.name}'" or nil
|
||||||
if calling_fn.linedefined == 0 then name = "main chunk"
|
if calling_fn.linedefined == 0 then name = "main chunk"
|
||||||
if name == "run_lua_fn" then continue
|
if name == "run_lua_fn" then continue
|
||||||
line = nil
|
line = nil
|
||||||
@ -1072,46 +1072,57 @@ OPTIONS
|
|||||||
assert(filename)
|
assert(filename)
|
||||||
file = FILE_CACHE[filename]\sub(tonumber(start),tonumber(stop))
|
file = FILE_CACHE[filename]\sub(tonumber(start),tonumber(stop))
|
||||||
err_line = get_line(file, calling_fn.currentline)\sub(1,-2)
|
err_line = get_line(file, calling_fn.currentline)\sub(1,-2)
|
||||||
offending_statement = colored.red(err_line)
|
offending_statement = colored.bright(colored.red(err_line\match("^[ ]*(.*)")))
|
||||||
line = colored.yellow("#{filename}:#{calling_fn.currentline}\n#{offending_statement}")
|
|
||||||
if arg_orders = nomsu.environment.ARG_ORDERS[calling_fn.func]
|
if arg_orders = nomsu.environment.ARG_ORDERS[calling_fn.func]
|
||||||
name = colored.bright(colored.yellow next(arg_orders))
|
name = "action '#{next(arg_orders)}'"
|
||||||
else
|
else
|
||||||
name = colored.bright(colored.yellow "main chunk")
|
name = "main chunk"
|
||||||
|
line = colored.yellow("#{filename}:#{calling_fn.currentline} in #{name}\n #{offending_statement}")
|
||||||
else
|
else
|
||||||
if calling_fn.istailcall and not name
|
|
||||||
name = "<tail call>"
|
|
||||||
ok, file = pcall ->FILE_CACHE[calling_fn.short_src]
|
ok, file = pcall ->FILE_CACHE[calling_fn.short_src]
|
||||||
if not ok then file = nil
|
if not ok then file = nil
|
||||||
local line_num
|
local line_num
|
||||||
if name == nil and debug.getinfo(level+1)
|
if name == nil
|
||||||
i = 1
|
search_level = level
|
||||||
while true
|
_info = debug.getinfo(search_level)
|
||||||
-- '+1' to get to one level higher than the callsite
|
while _info and (_info.func == pcall or _info.func == xpcall)
|
||||||
varname, val = debug.getlocal(level+1, i)
|
search_level += 1
|
||||||
|
_info = debug.getinfo(search_level)
|
||||||
|
if _info
|
||||||
|
for i=1,999
|
||||||
|
varname, val = debug.getlocal(search_level, i)
|
||||||
if not varname then break
|
if not varname then break
|
||||||
if val == calling_fn.func
|
if val == calling_fn.func
|
||||||
name = varname
|
name = "local '#{varname}'"
|
||||||
|
if not varname\match("%(")
|
||||||
|
break
|
||||||
|
unless name
|
||||||
|
for i=1,_info.nups
|
||||||
|
varname, val = debug.getupvalue(_info.func, i)
|
||||||
|
if not varname then break
|
||||||
|
if val == calling_fn.func
|
||||||
|
name = "upvalue '#{varname}'"
|
||||||
if not varname\match("%(")
|
if not varname\match("%(")
|
||||||
break
|
break
|
||||||
i += 1
|
|
||||||
if file and calling_fn.short_src\match(".moon$") and LINE_TABLES[file]
|
if file and calling_fn.short_src\match(".moon$") and LINE_TABLES[file]
|
||||||
char = LINE_TABLES[file][calling_fn.currentline]
|
char = LINE_TABLES[file][calling_fn.currentline]
|
||||||
line_num = 1
|
line_num = 1
|
||||||
for _ in file\sub(1,char)\gmatch("\n") do line_num += 1
|
for _ in file\sub(1,char)\gmatch("\n") do line_num += 1
|
||||||
line = colored.cyan("#{calling_fn.short_src}:#{line_num}")
|
line = colored.cyan("#{calling_fn.short_src}:#{line_num} in #{name or '?'}")
|
||||||
name = colored.bright(colored.cyan(name or "???"))
|
|
||||||
else
|
else
|
||||||
line_num = calling_fn.currentline
|
line_num = calling_fn.currentline
|
||||||
line = colored.blue("#{calling_fn.short_src}:#{calling_fn.currentline}")
|
if calling_fn.short_src == '[C]'
|
||||||
name = colored.bright(colored.blue(name or "???"))
|
line = colored.green("#{calling_fn.short_src} in #{name or '?'}")
|
||||||
|
else
|
||||||
|
line = colored.blue("#{calling_fn.short_src}:#{calling_fn.currentline} in #{name or '?'}")
|
||||||
|
|
||||||
if file
|
if file
|
||||||
err_line = get_line(file, line_num)\sub(1,-2)
|
err_line = get_line(file, line_num)\sub(1,-2)
|
||||||
offending_statement = colored.red(err_line)
|
offending_statement = colored.bright(colored.red(err_line\match("^[ ]*(.*)$")))
|
||||||
line ..= "\n "..offending_statement
|
line ..= "\n "..offending_statement
|
||||||
_from = colored.dim colored.white "|"
|
io.stderr\write(" #{line}\n")
|
||||||
io.stderr\write(("%32s %s %s\n")\format(name, _from, line))
|
if calling_fn.istailcall
|
||||||
|
io.stderr\write(" #{colored.dim colored.white " (...tail calls...)"}\n")
|
||||||
|
|
||||||
io.stderr\flush!
|
io.stderr\flush!
|
||||||
|
|
||||||
@ -1218,7 +1229,7 @@ OPTIONS
|
|||||||
--require('ProFi')\profile "scratch/profile.txt", (profi)->
|
--require('ProFi')\profile "scratch/profile.txt", (profi)->
|
||||||
do
|
do
|
||||||
ok, ldt = pcall(require,'ldt')
|
ok, ldt = pcall(require,'ldt')
|
||||||
if ok
|
if ok and false
|
||||||
ldt.guard run
|
ldt.guard run
|
||||||
else xpcall(run, err_hand)
|
else xpcall(run, err_hand)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user