开发者

dynamically load code and get line number of parse error

开发者 https://www.devze.com 2023-04-10 04:40 出处:网络
I have a tool, similar in ways to JSFiddle, that allows me to dynamically type in javascript and run it on a page.The code can be multiple lines, and typically will be.

I have a tool, similar in ways to JSFiddle, that allows me to dynamically type in javascript and run it on a page. The code can be multiple lines, and typically will be.

Unfortunately if there is an exception in the code I type in, I can't get the line number of the exception if I use eval() to run the code.

I found a partial solution, which is instead of using

try{
 eval(code);
 }
catch(e) {
 processException(e);
 }

to instead do something like this:

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

Now, if the code throws an exception, and I look at the stack trace(in my processException() function) I can get a line number of the exception (in firefox and chrome, anyway).

That's all well and good if it is actually a runtime exception, such as a variable not being defined. The problem is if there is a parse error / syntax error, such as mismatched parens or the like. I get nothing.

Is there any crazy workaround for this, that works on firefox and chrome, at a m开发者_JS百科inimum? Eval within eval within script tag within Function object? I'm trying everything and haven't found anything that works.


I found a reasonable solution finally.

First, I set window.onerror to some function. This doesn't get a full stack trace, but will get a file and line number.

Then, I do this:

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

Note that this doesn't actually run my code, as it simply creates a function (in global scope, with the name 'someUniqueGlobalName' -- which of course I'd really come up with a different name each time I do this).

If there is a syntax error, it will be caught in the window.onerror function, and I can get the error type and line number (which of course I'll have to subtract one from, since I added one line at the beginning).

Now, I unset window.onerror.

Finally, I run the code by calling someUniqueGlobalName() in a try/catch block. Here I can get a full stack trace with line numbers if there is a runtime error.


You could take it a step further and integrate JSLINT: https://github.com/douglascrockford/JSLint

It's pretty straightforward.. here's a quick test...

Download: https://raw.github.com/douglascrockford/JSLint/master/jslint.js

jshint_test.html:

<script type="text/javascript" src="jslint.js"></script>
<script>

var result = JSLINT("var some = true;\nif (some) {");

if (result)
{
  alert('Looking good');
}
else
{
  var error_message = '';
  for (i in JSLINT.errors)
  {
    var error = JSLINT.errors[i];
    error_message += error.reason + ' on line: ' + error.line + ' character: ' + error.character + "\n";
  }
  alert(error_message);
}
</script>

Check out the documentation. The second argument to JSLINT is an options object.. there are TONS of options.


Probably maybe just use https://github.com/mattdiamond/fuckitjs

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号