Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Line number of SyntaxError in Node.js

I have some code that uses vm module and runInNewContext function and executes dynamically generated JavaScript code. Basically a safer option of eval.

The code (variable code) can possibly contain syntax errors, so I would like to catch them and print some useful information.

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?
    }
}

I'd like to print the number of the line with the syntax error, but I have two problems:

  • I don't know how to recognize whether the exception is SyntaxError or something else. instaceof doesn't work (update - I can use e.name === "SyntaxError").
  • Even if I was able to recognize it, how could I get the line number? Is it possible?

Thanks in advance.

Update: I can get some information from e.stack - however, the topmost call in the stack trace is runInNewContext (with its line number), but I still can't find the line number inside code, which caused the exception (SyntaxError).

like image 616
Martin Majer Avatar asked Dec 13 '13 15:12

Martin Majer


People also ask

How do you get the line a error is on JS?

You just use (new Error). lineNumber to access the current line number in a script.

What Is syntax error JS?

The SyntaxError object represents an error when trying to interpret syntactically invalid code. It is thrown when the JavaScript engine encounters tokens or token order that does not conform to the syntax of the language when parsing code.

What is reference error and syntax error in JavaScript?

ReferenceError: Raised when an invalid reference is used. SyntaxError: Raised when a syntax error occurs while parsing JavaScript code. TypeError: Raised when the type of a variable is not as expected. strong text URIError: Raised when the encodeURI() or decodeURI() functions are used in an incorrect manner.


1 Answers

use a try/catch

store the stack in a global variable

log the sandbox

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));

this will log:

{ e: 'ReferenceError: count is not defined\n at myfile.vm:1:13\n ...

now you can see that the error occurs at line 1, character 13 of myfile.vm this will still require you to place some try/cathc blocks at various places but at least you can get feedback now

EDIT:

Adding a method to detect Syntax errors from within your running code

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

var result = acorn.parse(src);

doing this will result in a thrown Exception with "SyntaxError: Unexpected token (3:4)" eg. line 3, character 4 is the unexpected token, (the extra { that shouldnt be there)

like image 68
Paul Scheltema Avatar answered Sep 30 '22 14:09

Paul Scheltema