UNPKG

stackframes

Version:
91 lines (86 loc) 4.91 kB
const jsonloop = require('jsonloop') const cJSON = jsonloop() const methods = { "getThis": callsite => { // getThis: returns the value of this const self = callsite.getThis() const ctor = self.constructor const ctorName = ctor ? `:${ctor.name}` : '' const isGlobal = self === globalThis const type = `${isGlobal ? 'global' : 'local'}${ctorName}` var json try { json = isGlobal ? `${self}` : cJSON.stringify(self) } catch (error) { json = `${self}:${error}` } return { type, json } }, "getTypeName": callsite => callsite.getTypeName(), // getTypeName: returns the type of this as a string. This is the name of the function stored in the constructor field of this, if available, otherwise the object’s [[Class]] internal property. "getFunctionSource": callsite => { // getFunction: returns the current function const getF = callsite.getFunction() if (getF) return `${getF}` }, "getFunction": callsite => { // getFunction: returns the current function const getF = callsite.getFunction() if (getF) { const name = getF.name || '(anonymous)' const ctor = getF.constructor if (ctor) return { async: false, name } const ctorName = ctor.name === "AsyncFunction" return { type: ctorName, name } } }, "getFunctionName": callsite => callsite.getFunctionName(), // getFunctionName: returns the name of the current function, typically its name property. If a name property is not available an attempt is made to infer a name from the function’s context. "getMethodName": callsite => callsite.getMethodName(), // getMethodName: returns the name of the property of this or one of its prototypes that holds the current function "getFileName": callsite => callsite.getFileName(), // getFileName: if this function was defined in a script returns the name of the script "getLineNumber": callsite => callsite.getLineNumber(), // getLineNumber: if this function was defined in a script returns the current line number "getColumnNumber": callsite => callsite.getColumnNumber(), // getColumnNumber: if this function was defined in a script returns the current column number "getEvalOrigin": callsite => callsite.getEvalOrigin(), // getEvalOrigin: if this function was created using a call to eval returns a string representing the location where eval was called "isToplevel": callsite => callsite.isToplevel(), // isToplevel: is this a top-level invocation, that is, is this the global object? "isEval": callsite => callsite.isEval(), // isEval: does this call take place in code defined by a call to eval? "isNative": callsite => callsite.isNative(), // isNative: is this call in native V8 code? "isConstructor": callsite => callsite.isConstructor(), // isConstructor: is this a constructor call? "isAsync": callsite => callsite.isAsync(), // isAsync: is this an async call (i.e. await or Promise.all())? "isPromiseAll": callsite => callsite.isPromiseAll(), // isPromiseAll: is this an async call to Promise.all()? "getPromiseIndex": callsite => callsite.getPromiseIndex(), // getPromiseIndex: returns the index of the promise element that was followed in Promise.all() for async stack traces, or null if the CallSite is not a Promise.all() call. "NameOrSourceURL": callsite => callsite.getScriptNameOrSourceURL(), "getPosition": callsite => callsite.getPosition() } const defaultFlags = Object.keys(methods) stackframes.defaultFlags = defaultFlags module.exports = stackframes function stackframes (err = {}, flags = defaultFlags) { var depths, exclude if (!(err instanceof Error)) { if (!err) err = {} depths = err.depths exclude = err.exclude err = void 0 } if (!(depths > -1)) depths = Infinity if (typeof err === "number") (depths = err, err = void 0) const exclude_this_and_below = exclude || stackframes const oldLimit = Error.stackTraceLimit const v8Handler = Error.prepareStackTrace Error.stackTraceLimit = depths Error.prepareStackTrace = prepareStackTrace if (!err) (err = {}, Error.captureStackTrace(err, exclude_this_and_below)) const extractor = extract.bind(flags) const frames = err.stack.map(extractor) Error.prepareStackTrace = v8Handler Error.stackTraceLimit = oldLimit return frames } function prepareStackTrace (_, stack) { return stack } function extract (callsite) { const flags = this const frame = {} for (var i = 0, len = flags.length; i < len; i++) { const flag = flags[i] const fn = methods[flag] if (fn) frame[flag] = fn(callsite) } return frame }