Clients/Client2020/ExtraContent/LuaPackages/ErrorReporters/Backtrace/ProcessErrorStack.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