Node.js中SyntaxError的行号

时间:2013-12-13 15:47:45

标签: javascript node.js exception v8

我有一些使用vm模块和runInNewContext函数的代码,并执行动态生成的JavaScript代码。基本上是eval的更安全选项。

代码(变量code)可能包含语法错误,因此我想抓住它们并打印一些有用的信息。

try {
    vm.runInNewContext(code, sandbox, filename);
}
catch (e) {
    if (e instanceof SyntaxError) { // always false
        console.log(e.toString()); // "SyntaxError: Unexpected token ||" for example
        console.log(e.line); // how to get the line number?
    }
}

我想用语法错误打印行号,但我有两个问题:

  • 我不知道如何识别异常是SyntaxError还是其他。 instaceof不起作用(更新 - 我可以使用e.name === "SyntaxError")。
  • 即使我能够识别它,我怎么能得到行号?有可能吗?

提前致谢。

更新:我可以从e.stack获取一些信息 - 但是,堆栈跟踪中最顶层的调用是runInNewContext(带有行号),但我仍然找不到内部的行号code,导致异常(SyntaxError)。

4 个答案:

答案 0 :(得分:3)

1)使用if (e.name === "SyntaxError")

2)与错误相关的所有数据都保存在e.stack

答案 1 :(得分:2)

使用try / catch

将堆栈存储在全局变量

记录沙箱

var util = require('util');
var vm = require('vm');
var sandbox = {e:null};
var src = 'try{count += 1;}catch(err) {e=err.stack}';

vm.runInNewContext(src , sandbox, 'myfile.vm');
console.log(util.inspect(sandbox));

这将记录:

  

{e:'ReferenceError:count未在myfile.vm中定义\ n:1:13 \ n   ...

现在您可以看到错误发生在myfile.vm的第1行,第13行 这仍然需要你在不同的地方放置一些try / cathc块 但至少你现在可以得到反馈

编辑:

添加一种方法来检测正在运行的代码中的语法错误

var acorn = require('acorn');
var src = "try{\n"+
    "   {" +
    "       count += 1;\n"+
    "   }catch(err) {\n" +
    "       e=err.stack\n" +
    "}";

var result = acorn.parse(src);
执行此操作将导致抛出异常 “SyntaxError:意外的令牌(3:4)” 例如。第3行,第4个字符是意外的标记,(额外的{不应该存在)

答案 2 :(得分:0)

虽然有点(非常)旧,但您可以使用stackedy module,这可以帮助您操纵堆栈跟踪。但它并不是完美的解决方案,因为显示的行号是函数调用中的行号,而不是源文件中的行号。

请特别注意simple example

index.js

var stackedy = require('stackedy');
var fs = require('fs');

var src = fs.readFileSync(__dirname + '/src.js');
var stack = stackedy(src, { filename : 'stax.js' }).run();

stack.on('error', function (err, c) {
    stack.stop();
    console.log('Error: ' + err);

    var cur = c.current;
    console.log('  in ' + cur.filename + ' at line ' + cur.start.line);

    c.stack.forEach(function (s) {
        console.log('  in ' + s.filename + ', '
            + s.functionName + '() at line ' + s.start.line
        );
    });
});

src.js

function f () { g() }
function g () { h() }
function h () { throw new SyntaxError('woops') }

f();

输出:

~/tmp ❯❯❯ node index.js
Error: SyntaxError: woops
  in stax.js at line 2
  in stax.js, h() at line 1
  in stax.js, g() at line 0
  in stax.js, f() at line 4

如评论中所述,您可以使用err.name === 'SyntaxError'来检查错误类型。

答案 3 :(得分:0)

对于* nix:

if (err) console.log(err.stack.split('\n')[1]);

它将记录第二行stacktrace,即发生错误的位置。

Windows或Mac可能需要其他拆分符号(取决于系统行结尾)