我有一些使用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
)。
答案 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可能需要其他拆分符号(取决于系统行结尾)