10

假设我有一种看起来像的语言

print "Hello World"

转换为

var $__Helpers = {
    print: function(s) {
        if (typeof s != 'string')
            throw new TypeError('String expected');
        console.log(s);
    }
};

$__Helpers.print("Hello World");

如果这种语言的用户

print 5

$__Helpers.print说“预期字符串”会抛出 TypeError 。我希望开发人员工具将该print 5行显示为此错误的原始调用。我知道如何让我的源映射显示一个看起来像的调用堆栈

transpiled_script.js:2
original_script.os:1

其中transpiled_script.js:2$__Helpers.print函数调用original_script.os:1的脚本和行号,是调用的脚本和行号print 5。我想让开发工具忽略对顶部的调用transpiled_script.js(这只是我的转译器的一个实现细节),只显示来自原始脚本的调用(这是他们应该在自己的脚本中调试的部分)。

我显然不能简单地映射transpiled_script.js:2到,original_script.os:1因为可能会多次调用printinside original_script.os,所以这不是一对一的关系。

有没有办法做到这一点?

(我正在使用 escodegen 生成我的源代码和源映射(escodegen 使用 Node mozilla/source-map 模块),因此有一种方法可以告诉 escodegen 或 mozilla/source-map 这样做是理想的,但我可以覆盖escodegen 的输出,如果那是不可能的。)

4

1 回答 1

3

您可以拆分跟踪并打印所需的行

var $__Helpers = {
    print: function(s) {
        if (typeof s != 'string'){
            var err = new TypeError('String expected');
            var trace = err.stack.split('\n')
            console.error(trace[0]); // TypeError: string expected
            console.error(trace[2]); // the line who called the function, probably 
            //original_script.os:1, or whatever line number the call was from
            //quit the script

        }
        console.log(s);
    } };

编辑:更好的解决方案是替换错误的痕迹,而不是抛出它,代码现在看起来像这样:

var $__Helpers = {
    print: function(s) {
        if (typeof s != 'string'){
            var err = new TypeError('String expected: Got'+s);
            err.stack = err.stack.replace(/\n.*transpiled_script\.js.*?\n/g,"\n");
            throw err;

        }
        console.log(s);
    } };

这也适用于嵌套调用中的错误。

于 2013-10-04T20:00:04.360 回答