102 lines
2.3 KiB
Lua
102 lines
2.3 KiB
Lua
--[[
|
|
Module for splitting the errorStack string to a list.
|
|
|
|
Currently works with:
|
|
Pattern of error from ScriptContext.Error:
|
|
see ScriptContext.extractCallStack
|
|
|
|
Pattern of error from ScriptContext.Error: (luau)
|
|
see ScriptContext.extractCallStack
|
|
|
|
Pattern of error from debug.traceback:
|
|
see ScriptContext.printCallStack
|
|
|
|
Pattern of error from debug.traceback: (luau)
|
|
see luau_backtrace
|
|
]]
|
|
|
|
local function splitStringWithMarks(string, matches)
|
|
if type(string) ~= "string" or
|
|
type(matches) ~= "table" then
|
|
return string, ""
|
|
end
|
|
|
|
for _, match in ipairs(matches) do
|
|
local start, stop = string.find(string, match, nil, true)
|
|
|
|
if start ~= nil then
|
|
local first = string.sub(string, 1, start - 1)
|
|
local rest = string.sub(string, stop + 1)
|
|
return first, rest
|
|
end
|
|
end
|
|
|
|
return string, ""
|
|
end
|
|
|
|
local function findFileNameFromPath(pathStr)
|
|
if type(pathStr) ~= "string" then
|
|
return ""
|
|
end
|
|
|
|
return string.match(pathStr, "([^.]*)$")
|
|
end
|
|
|
|
local function ProcessErrorStack(errorStack)
|
|
local stack = {}
|
|
local sourceCodeDict = {}
|
|
local numOfSourceCode = 0
|
|
|
|
if type(errorStack) ~= "string" then
|
|
return stack, sourceCodeDict
|
|
end
|
|
|
|
for line in errorStack:gmatch("[^\r\n]+") do
|
|
local newLine
|
|
local source
|
|
local funcName
|
|
local lineNumber
|
|
|
|
source, newLine = splitStringWithMarks(line, {", line ", ", Line ", ":"})
|
|
lineNumber, funcName = splitStringWithMarks(newLine, {" - "})
|
|
|
|
if lineNumber ~= "" and source ~= "" then
|
|
-- Convert "Script 'filePath'" to filePath
|
|
local _, _, matchedSource = string.find(source, "Script '(.*)'")
|
|
if matchedSource ~= nil then
|
|
source = matchedSource
|
|
end
|
|
|
|
local index = sourceCodeDict[source]
|
|
if index == nil then
|
|
numOfSourceCode = numOfSourceCode + 1
|
|
index = numOfSourceCode
|
|
sourceCodeDict[source] = index
|
|
end
|
|
|
|
-- If no funcName is provided, Backtrace has difficulty differentiating the error
|
|
-- stacks apart. So we want to have something.
|
|
if funcName == "" then
|
|
funcName = findFileNameFromPath(source)
|
|
end
|
|
|
|
table.insert(stack, {
|
|
line = lineNumber,
|
|
funcName = funcName,
|
|
sourceCode = tostring(index),
|
|
})
|
|
end
|
|
end
|
|
|
|
local sourceCodeOutput = {}
|
|
for path, index in pairs(sourceCodeDict) do
|
|
sourceCodeOutput[tostring(index)] = {
|
|
path = path,
|
|
}
|
|
end
|
|
|
|
return stack, sourceCodeOutput
|
|
end
|
|
|
|
return ProcessErrorStack
|