Here is the main function which can be called from anywhere in your code with a new Error() parameter to locate the function call and its path/hierarchy of calls. Please note that the output of the trace depends on where you create the Error() object.
function trace(e) {
if (!e) e = new Error()
let result
const errStack = e.stack
if (errStack) {
const stackArr = errStack.split('\n')
const fDetailsArr = []
let fDetails // function details
stackArr.forEach(line => {
fDetails = extract(line)
if (fDetails)
if (fDetails.fn)
if (fDetails.fn.indexOf('.') <= 0) // system/framework objects generally have '.'
fDetailsArr.push(fDetails.fp)
})
if (fDetailsArr.length > 0) {
fDetailsArr.reverse()
result = fDetailsArr.join(' ==> ')
}
}
return result
}
This function takes the help of the following helper function to extract the function details from each line of the trace.
function extract(line) {
let fp, fn, fl // function path (name+location), function name, function location
let pathArr, pathLocIndex = -1, fnPart, fnParts, flPart
if (line) {
const parts = line.split('(')
if (parts.length > 1) {
fnPart = parts[0] // file name part
flPart = parts[1] // file location part
if (fnPart && flPart) {
fnParts = fnPart.split('at ')
if (fnParts.length > 1) fn = fnParts[1] // function name
if (flPart.indexOf('\\') >= 0)
pathArr = flPart.split('\\')
else if (flPart.indexOf('/') >= 0)
pathArr = flPart.split('/') // cloud function run file path has this
if (pathArr) pathLocIndex = pathArr.length - 1
if (pathLocIndex > 0) {
fl = '(' + pathArr[pathLocIndex] // function file path and location of the code
fp = fn + fl
if (fn) fn = fn.trim() // file name has a trailing space
}
}
}
}
if (fp)
return { fp, fn, fl }
else return null
}
I have also used this custom function call tracer to enhance my custom logger function which you can read at Handling Complex Logs better for Google Cloud Functions.
Thank you.
Post a Comment