Skip to content

displayErrors option of the vm module seems not to work well #4835

Closed
@susisu

Description

@susisu

I'm stuck for the behavior of the displayErrors option of the vm module.

First I wrote the code like below and this works well.

var vm = require("vm");
var sandbox = Object.create(null);
var context = vm.createContext(sandbox);
var script  = new vm.Script("?", { filename: "foobar", displayErrors: false });
script.runInContext(context, { filename: "foobar", displayErrors: false });
foobar:1
?
^

SyntaxError: Unexpected token ?
    at Object.<anonymous> (/path/to/file.js:4:15)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Function.Module.runMain (module.js:447:10)
    at startup (node.js:139:18)
    at node.js:999:3

When displayErrors are set to true, however, the behavior seems to be not consistent with the document "print any errors to stderr before throwing an exception" since this code does not output anything to stderr.

var vm = require("vm");
var sandbox = Object.create(null);
var context = vm.createContext(sandbox);
var script  = new vm.Script("?", { filename: "foobar", displayErrors: true });
script.runInContext(context, { filename: "foobar", displayErrors: true });
foobar:1
?
^

SyntaxError: Unexpected token ?
    at Object.<anonymous> (/Users/Susisu/root/projects/est/dev/vmtest.js:4:15)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Function.Module.runMain (module.js:447:10)
    at startup (node.js:139:18)
    at node.js:999:3

Next, I tried to catch the error and get the information where the error has occurred but I couldn't.

I also re-threw the error and found that the information about the script is discarded when the error is re-thrown if displayErrors: false, while the displayErrors: true version retains it.

var vm = require("vm");
var sandbox = Object.create(null);
var context = vm.createContext(sandbox);
try {
    var script  = new vm.Script("?", { filename: "foobar", displayErrors: false });
    script.runInContext(context, { filename: "foobar", displayErrors: false });
}
catch (err) {
    throw err;
}
/path/to/file.js:9
    throw err;
    ^

SyntaxError: Unexpected token ?
    at Object.<anonymous> (/path/to/file.js:5:19)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Function.Module.runMain (module.js:447:10)
    at startup (node.js:139:18)
    at node.js:999:3
var vm = require("vm");
var sandbox = Object.create(null);
var context = vm.createContext(sandbox);
try {
    var script  = new vm.Script("?", { filename: "foobar", displayErrors: true });
    script.runInContext(context, { filename: "foobar", displayErrors: true });
}
catch (err) {
    throw err;
}
foobar:1
?
^

SyntaxError: Unexpected token ?
    at Object.<anonymous> (/path/to/file.js:5:19)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Function.Module.runMain (module.js:447:10)
    at startup (node.js:139:18)
    at node.js:999:3

The problem is more serious when combined with Promise.
This code actually does not print anything since the error is swallowed by the Promise, and I have no idea to know where the error occurred in the script.

var vm = require("vm");
new Promise((resolve, reject) => {
    var sandbox = Object.create(null);
    var context = vm.createContext(sandbox);
    var script  = new vm.Script("?", { filename: "foobar", displayErrors: false });
    script.runInContext(context, { filename: "foobar", displayErrors: false });
}).catch(err => {
    // can't do anything
});

Note that all the codes throw syntax errors, but the results are almost same for throwing runtime errors.

Taken together, it seems that displayErrors: true does only make the error retain the information where it occurred and does not let new vm.Script (and runInContext or something) print anything.
In addition, there seems to be no way to know where the error occurred if it is in Promise.

Here I have two questions.

  1. Is this behavior of displayErrors: true is correct?
  2. Are there some ways to know where the error occurred in the script for the last case?

The version of Node.js is v5.5.0.

Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-bugIssues with confirmed bugs.vmIssues and PRs related to the vm subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions