动态加载代码并获取解析错误的行号

rob*_*rob 7 javascript

我有一个类似于JSFiddle的工具,它允许我动态输入javascript并在页面上运行它.代码可以是多行,通常也是.

不幸的是,如果我输入的代码中有异常,如果我使用eval()来运行代码,我就无法得到异常的行号.

我找到了一个部分解决方案,而不是使用

try{
 eval(code);
 }
catch(e) {
 processException(e);
 }
Run Code Online (Sandbox Code Playgroud)

而是做这样的事情:

var s = document.createElement('script');
s.appendChild(document.createTextNode(
    "try{\n" + 
     code +
     "}catch(e){processException(e)}"));
document.body.appendChild(s);
Run Code Online (Sandbox Code Playgroud)

现在,如果代码抛出一个异常,我期待在堆栈跟踪(在我processException()函数),我可以得到异常的行号(在Firefox和Chrome,反正).

如果它实际上是一个运行时异常,例如未定义的变量,这一切都很好.问题是是否存在解析错误/语法错误,例如不匹配的parens等.我一无所获.

有没有任何疯狂的解决方法,至少适用于Firefox和Chrome?在Function对象中的脚本标记内的eval中的Eval?我正在尝试一切,但没有找到任何有用的东西.

rob*_*rob 3

我终于找到了一个合理的解决方案。

首先,我将 window.onerror 设置为某个函数。这不会获得完整的堆栈跟踪,但会获得文件和行号。

然后,我这样做:

var s = document.createElement('script');
s.appendChild(document.createTextNode(
    "var someUniqueGlobalName = function () {\n" +
     code +
     "\n};";
document.body.appendChild(s);
Run Code Online (Sandbox Code Playgroud)

请注意,这实际上并没有运行我的代码,因为它只是创建一个函数(在全局范围内,名称为“someUniqueGlobalName”——当然,每次我这样做时我都会想出一个不同的名称)。

如果存在语法错误,它将在 window.onerror 函数中捕获,并且我可以获得错误类型和行号(当然我必须从中减去一,因为我在开头添加了一行) 。

现在,我取消了 window.onerror 的设置。

最后,我通过在 try/catch 块中调用 someUniqueGlobalName() 来运行代码。如果存在运行时错误,我可以在这里获得带有行号的完整堆栈跟踪。