Javascript 删除堆栈跟踪字符串中的最后一项

Javascript remove last item in stack trace string

我正在创建一个 Javascript 记录器,在其中,对于错误消息,我还添加了这样的堆栈跟踪:

function logMessage(logMessage) 
{
  let stackTrace = new Error().stack;
  logMessage.stackTrace = stackTrace;
  ...
}

这给了我堆栈跟踪,但它也显然将 logMessage 本身的方法添加为堆栈中的最后一项...

如何删除最后一条跟踪,以便我只能看到调用 logMessage 之前的跟踪,但没有 logMessage 本身?

方法很简单,因为我们得到的堆栈是一个字符串除以 \n,格式如下:

ERROR \n
at ... \n
at ... \n

所以我们需要做的就是:

let stackTrace = new Error().stack;   //get the stack trace string
let arr = stackTrace.split("\n");     //create an array with all lines
arr.splice(1,1);                      //remove the second line (first line after "ERROR")
stackTrace = arr.join("\n");          //join array back to a string

堆栈跟踪 returns 以错误消息开头的多行字符串,然后是所有以 at {function name/position} 开头的行;

您可以简单地更改多行字符串并使用 splitfilterjoin

绕过第一次出现的 at {function name/position}
stackTrace.split('\n').filter(function(line, index) { return index !== 1 }).join('\n');

查看代码段示例

function deepFunctionStack() {
  return new Error().stack;
}

function layer1Function() {
  return deepFunctionStack();
}

function topLayerFunction() {
  return layer1Function();
}

var originalStack = topLayerFunction();
var formattedStack = originalStack.split('\n').filter(function(line, index) { return index !== 1 }).join('\n');
document.write('Original Stack:');
document.write('<pre>' + originalStack + '</pre>');

document.write('Formatted Stack:');
document.write('<pre>' + formattedStack + '</pre>');

这是处理 Firefox、Chrome 和 IE 堆栈跟踪之间差异的附加版本。它将从 Chrome 和 IE 中删除初始的“ERROR”行。它也比此处列出的其他版本快得多。

// stack: string - call stack string
// levels: int - number of levels to remove from the top of the call stack
function trimCallStack(stack, levels) {
    if (stack) {
        const newLineChar = "\n"; // Each line deliminated by '\n'
        const isFirefoxCallStack = stack.indexOf("@") > -1; // If stacktrace contains '@' it is FireFox
        // remove an additional line if browser is NOT FireFox (i.e. Chrome or IE) since those start stack trace with the error name
        // remove N additional lines specified by `levels`
        let iterations = (isFirefoxCallStack ? 0 : 1) + (levels ?? 0);
        let start = 0;
        while(iterations-- && start !== -1) {
            start = stack.indexOf(newLineChar, start + 1);
        }
        
        stack = start !== -1 ? stack.substring(start + 1) : ""; // start === -1 if removing more lines than exist, so return "" in that case
    }

    return stack || "";
}

来自 FireFox 和 Chrome/IE 的堆栈跟踪示例:

Chrome/IE 堆栈跟踪:

Error: fail
    at test (<anonymous>:2:8)
    at test1 (<anonymous>:5:5)
    at test2 (<anonymous>:8:5)
    at test3 (<anonymous>:11:5)
    at <anonymous>:1:5

Firefox 堆栈跟踪:

test@debugger eval code:2:8
test1@debugger eval code:5:5
test2@debugger eval code:8:5
test3@debugger eval code:11:5
@debugger eval code:1:5

使用提供的功能后:

Chrome/IE 堆栈跟踪:

    at test (<anonymous>:2:8)
    at test1 (<anonymous>:5:5)
    at test2 (<anonymous>:8:5)
    at test3 (<anonymous>:11:5)
    at <anonymous>:1:5

Firefox 堆栈跟踪:

test@debugger eval code:2:8
test1@debugger eval code:5:5
test2@debugger eval code:8:5
test3@debugger eval code:11:5
@debugger eval code:1:5