125 lines
2.8 KiB
Lua
125 lines
2.8 KiB
Lua
local setmetatable = setmetatable
|
|
local error = error
|
|
local type = type
|
|
local traceback = debug.traceback
|
|
|
|
--- @class aspect.error
|
|
--- @field code string
|
|
--- @field line number
|
|
--- @field name string
|
|
--- @field message string
|
|
--- @field callstack string
|
|
--- @field traceback string
|
|
--- @field context string
|
|
local err = {
|
|
_NAME = "error"
|
|
}
|
|
|
|
--- @param e aspect.error
|
|
local function to_string(e)
|
|
local msg
|
|
if e.name then
|
|
msg = e.code .. " error: " .. e.message .. " in " .. e.name .. ":" .. e.line
|
|
else
|
|
msg = e.code .. " error: " .. e.message
|
|
end
|
|
if e.context then
|
|
msg = msg .. "\nContext: " .. e.context .. " <-- there"
|
|
end
|
|
if e.callstack then
|
|
msg = msg .. "\nCallstack:\n" .. e.callstack
|
|
end
|
|
if e.traceback then
|
|
msg = msg .. "\nLua " .. e.traceback
|
|
end
|
|
return msg
|
|
end
|
|
|
|
local mt = {
|
|
__index = err,
|
|
__tostring = to_string
|
|
}
|
|
|
|
--- @param tok aspect.tokenizer
|
|
--- @param code string
|
|
--- @param message string
|
|
function err.compiler_error(tok, code, message)
|
|
local fields = {
|
|
code = code,
|
|
traceback = traceback(),
|
|
}
|
|
if tok then
|
|
if code == "syntax" then
|
|
if tok:is_valid() then
|
|
fields.message = "unexpected token '" .. tok:get_token() .. "', " .. message
|
|
else
|
|
fields.message = "unexpected end of tag, " .. message
|
|
end
|
|
else
|
|
fields.message = message
|
|
end
|
|
fields.context = tok:get_path_as_string()
|
|
else
|
|
fields.message = message
|
|
end
|
|
error(fields)
|
|
end
|
|
|
|
--- @param __ aspect.output
|
|
--- @param message string|aspect.error
|
|
function err.runtime_error(__, message)
|
|
error(err.new_runtime(__, message))
|
|
end
|
|
|
|
function err.is(wtf)
|
|
return type(wtf) == "table" and wtf._NAME == "error"
|
|
end
|
|
|
|
--- @param __ aspect.output
|
|
--- @param e aspect.error|string|table
|
|
function err.new_runtime(__, e)
|
|
if not err.is(e) then
|
|
e = err.new(e, "runtime")
|
|
end
|
|
e:set_name(__.view.name, __.line, __:get_callstack())
|
|
return e
|
|
end
|
|
|
|
function err.new(e, code)
|
|
if type(e) ~= 'table' then
|
|
e = {
|
|
message = tostring(e),
|
|
}
|
|
elseif e._NAME == "error" then
|
|
return e
|
|
end
|
|
|
|
return setmetatable({
|
|
code = e.code or code or "internal",
|
|
line = e.line or 0,
|
|
name = e.name or "runtime",
|
|
message = e.message or 'problems',
|
|
callstack = nil,
|
|
traceback = e.traceback or traceback(),
|
|
context = e.context,
|
|
}, mt)
|
|
end
|
|
|
|
function err:set_code(code)
|
|
self.code = code
|
|
return self
|
|
end
|
|
|
|
function err:set_name(name, line, callstack)
|
|
self.name = name or 'unknown'
|
|
self.line = line or 0
|
|
self.callstack = callstack
|
|
return self
|
|
end
|
|
|
|
function err:get_message()
|
|
return self.message
|
|
end
|
|
|
|
|
|
return err |