从chrome扩展内容脚本中抛出调试

时间:2013-11-29 17:09:00

标签: javascript google-chrome-extension stack-trace

短版

尝试编写一个返回调用堆栈的调试命令,减去当前位置。我以为我会用:

try {
    throw new Error(options["msg"])
} catch (e) {
    e.stack.shift;
    throw (e);
}

但我不知道该怎么做。显然我不能只是e.stack.shift那样。这也总是使它成为Uncaught Error - 但这些只是调试消息。

长版

我觉得我的内容脚本需要一个调试库。这是:

debug.js

var debugKeys = {
    "level": ["off", "event", "function", "timeouts"],
    "detail": ["minimal", "detailed"]
};
var debugState = { "level": "off", "detail": "minimal" };

function debug(options) {
    if ("level" in options) {
        if (verifyDebugValue("level", options["level"]) == false)
            return
    }
    if ("detail" in options) {
        if (verifyDebugValue("detail", options["detail"]) == false)
            return
    }

    console.log(options["msg"]);
}

function verifyDebugValue(lval, rval){
    var state = 10; // sufficiently high
    for (k in debugKeys[lval]) {
        if (debugKeys[lval][k] == rval) {
            return true;
        }
        if (debugKeys[lval][k] == debugState[lval]) { // rval was greater than debug key
            return false;
        }
    }
}

使用它时,您可以更改代码中的debugState以满足您的需要。它仍然是一项正在进行的工作,但它的工作正常。

要从其他内容脚本中使用它,只需将其加载到清单中,如:

的manifest.json

  "content_scripts": [
    {
      "js": ["debug.js", "foobar.js"],
    }
  ],

然后将其称为:

debug({"level": "timeouts", "msg": "foobar.js waitOnElement() timeout"});

生成:

foobar.js waitOnElement() timeout debug.js:17

还有我的问题。目前,它正在使用控制台日志,因此所有调试语句都来自同一个debug.js行。我宁愿返回调用上下文。我想我需要这样的东西:

try {
    throw new Error(options["msg"])
} catch (e) {
    e.stack.shift;
    throw (e);
}

但我不知道该怎么做。显然我不能只是e.stack.shift那样。这也总是使它成为Uncaught Error - 但这些只是调试消息。

1 个答案:

答案 0 :(得分:0)

您无法避免在debug.js中提及该行,因为使用throw (...)console.log/error(...) debug.js将发出命令。

你能做什么,你的代码中有一些try-catch块,然后在catch块中将错误对象传递给你的调试函数,调试函数将根据它的debugState处理它。

在任何情况下,您都不清楚如何使用调试库(以及为什么需要从堆栈跟踪中删除最后一个调用,但您可以尝试这样的事情:

  1. 将堆栈跟踪(实际上是多行字符串)拆分为行。
  2. 隔离不属于错误消息的第一行(对应于最后一次调用)。
  3. 将删除的行放在一起新的堆栈跟踪。
  4. E.g:

    function removeLastFromStack(stack, errMsg) {
        var firstLines = 'Error: ' + errMsg + '\n';
        var restOfStack = stack
                .substring(firstLines.length)   // <-- skip the error's message
                .split('\n')                    // <-- split into lines
                .slice(1)                       // <-- "slice out" the first line
                .join('\n');                    // <-- put the rest back together
        return firstLines + restOfStack;
    }
    
    function myDebug(err) {
        /* Based on my `debugState` I should decide what to do with this error.
         * E.g. I could ignore it, or print the message only, 
         * or print the full stack-trace, or alert the user, or whatever */
        var oldStack = err.stack;
        var newStack = removeLastFromStack(oldStack, err.message);
        console.log(newStack);
        //or: console.error(newStack);
    }
    
    /* Somewhere in your code */
    function someFuncThatMayThrowAnErr(errMsg) {
        throw new Error(errMsg);
    }
    
    try {
        someFuncThatMayThrowAnErr('test');
    } catch (err) {
        myDebug(err);
    }
    

    ...但我仍然没有看到如何删除跟踪中的最后一个调用会有所帮助