Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
10ba94f
Refactor self=this
benjamingr Jan 24, 2016
60e4ad3
Update self=this in http.js
benjamingr Jan 24, 2016
1ebb5b2
Refactor self=this to arrows
benjamingr Jan 24, 2016
dd96a00
fix leading whitespace linter issue
benjamingr Jan 24, 2016
889f467
fix emberrasing mistake
benjamingr Jan 25, 2016
5f8b49d
doc: undo move http.IncomingMessage.statusMessage
techjeffharris Jan 22, 2016
e82760f
doc: check for errors in 'listen' event
benjamingr Jan 24, 2016
efc4f01
vm: introduce `cachedData`/`produceCachedData`
indutny Jan 21, 2016
0e16694
test: mark test-tick-processor flaky
Trott Jan 21, 2016
29775ae
stream: refactor redeclared variables
Trott Jan 22, 2016
1164bcb
doc: fix code type of markdowns
JacksonTian Jan 25, 2016
d3ce9d3
doc: add `servername` parameter docs
estliberitas Jan 17, 2016
085c5a0
dns: throw a TypeError in lookupService with invalid port
evanlucas Jan 24, 2016
38aa39d
test: refactor test-net-settimeout
Trott Jan 21, 2016
516d5da
test: fs.link() test runs on same device
drewfish Jan 25, 2016
935768b
tools: enable assorted ESLint error rules
silverwind Jan 25, 2016
a6f50c6
test: fix irregular whitespace issue
silverwind Jan 25, 2016
db19416
src: attach error to stack on displayErrors
cjihrig Jan 26, 2016
25c4f98
tools: add support for subkeys in release tools
MylesBorins Jan 21, 2016
1348386
doc: fix nonsensical grammar in Buffer::write
Jimbly Jan 25, 2016
69176e1
doc: keep the names in sorted order
thefourtheye Jan 26, 2016
4b876bf
doc: remove unnecessary bind(this)
wKich Jan 21, 2016
5d8a742
tls: scope loop vars with let
Trott Jan 25, 2016
e99a50d
test: scope redeclared variable
Trott Jan 14, 2016
ae09fc2
doc: document deprecation of util._extend
benjamingr Jan 27, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
src: attach error to stack on displayErrors
The vm module's displayErrors option attaches error arrow
messages as a hidden property. Later, core JavaScript code
can optionally decorate the error stack with the arrow message.
However, when user code catches an error, it has no way to
access the arrow message. This commit changes the behavior of
displayErrors to mean "decorate the error stack if an error
occurs."

Fixes: #4835
PR-URL: #4874
Reviewed-By: Ben Noordhuis <[email protected]>
  • Loading branch information
cjihrig authored and benjamingr committed Jan 27, 2016
commit db1941665da8bbbc9678b8827973ef250401d77f
24 changes: 12 additions & 12 deletions doc/api/vm.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ The options when creating a script are:
displayed in stack traces
- `columnOffset`: allows you to add an offset to the column number that is
displayed in stack traces
- `displayErrors`: whether or not to print any errors to stderr, with the
line of code that caused them highlighted, before throwing an exception.
Applies only to syntax errors compiling the code; errors while running the
code are controlled by the options to the script's methods.
- `displayErrors`: if `true`, on error, attach the line of code that caused
the error to the stack trace. Applies only to syntax errors compiling the
code; errors while running the code are controlled by the options to the
script's methods.
- `timeout`: a number of milliseconds to execute `code` before terminating
execution. If execution is terminated, an [`Error`][] will be thrown.
- `cachedData`: an optional `Buffer` with V8's code cache data for the supplied
Expand Down Expand Up @@ -150,10 +150,10 @@ The options for running a script are:
displayed in stack traces
- `columnOffset`: allows you to add an offset to the column number that is
displayed in stack traces
- `displayErrors`: whether or not to print any errors to stderr, with the
line of code that caused them highlighted, before throwing an exception.
Applies only to runtime errors executing the code; it is impossible to create
a `Script` instance with syntax errors, as the constructor will throw.
- `displayErrors`: if `true`, on error, attach the line of code that caused
the error to the stack trace. Applies only to runtime errors executing the
code; it is impossible to create a `Script` instance with syntax errors, as
the constructor will throw.
- `timeout`: a number of milliseconds to execute the script before terminating
execution. If execution is terminated, an [`Error`][] will be thrown.

Expand Down Expand Up @@ -290,10 +290,10 @@ e.g. `(0,eval)('code')`. However, it also has the following additional options:
displayed in stack traces
- `columnOffset`: allows you to add an offset to the column number that is
displayed in stack traces
- `displayErrors`: whether or not to print any errors to stderr, with the
line of code that caused them highlighted, before throwing an exception.
Will capture both syntax errors from compiling `code` and runtime errors
thrown by executing the compiled code. Defaults to `true`.
- `displayErrors`: if `true`, on error, attach the line of code that caused
the error to the stack trace. Will capture both syntax errors from compiling
`code` and runtime errors thrown by executing the compiled code. Defaults to
`true`.
- `timeout`: a number of milliseconds to execute `code` before terminating
execution. If execution is terminated, an [`Error`][] will be thrown.

Expand Down
18 changes: 6 additions & 12 deletions lib/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,6 @@ function hasOwnProperty(obj, prop) {
}


function tryWrapper(wrapper, opts) {
try {
return runInThisContext(wrapper, opts);
} catch (e) {
internalUtil.decorateErrorStack(e);
throw e;
}
}


function stat(filename) {
filename = path._makeLong(filename);
const cache = stat.cache;
Expand Down Expand Up @@ -394,8 +384,12 @@ Module.prototype._compile = function(content, filename) {
// create wrapper function
var wrapper = Module.wrap(content);

var compiledWrapper = tryWrapper(wrapper,
{ filename: filename, lineOffset: 0 });
var compiledWrapper = runInThisContext(wrapper, {
filename: filename,
lineOffset: 0,
displayErrors: true
});

if (global.v8debug) {
if (!resolvedArgv) {
// we enter the repl if we're not given a filename argument.
Expand Down
5 changes: 3 additions & 2 deletions src/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@
'global.require = require;\n' +
'return require("vm").runInThisContext(' +
JSON.stringify(body) + ', { filename: ' +
JSON.stringify(name) + ' });\n';
JSON.stringify(name) + ', displayErrors: true });\n';
// Defer evaluation for a tick. This is a workaround for deferred
// events not firing when evaluating scripts from the command line,
// see https://github.com/nodejs/node/issues/1600.
Expand Down Expand Up @@ -988,7 +988,8 @@

var fn = runInThisContext(source, {
filename: this.filename,
lineOffset: 0
lineOffset: 0,
displayErrors: true
});
fn(this.exports, NativeModule.require, this, this.filename);

Expand Down
28 changes: 26 additions & 2 deletions src/node_contextify.cc
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ class ContextifyScript : public BaseObject {

if (v8_script.IsEmpty()) {
if (display_errors) {
AppendExceptionLine(env, try_catch.Exception(), try_catch.Message());
DecorateErrorStack(env, try_catch);
}
try_catch.ReThrow();
return;
Expand Down Expand Up @@ -640,6 +640,30 @@ class ContextifyScript : public BaseObject {
}
}

static void DecorateErrorStack(Environment* env, const TryCatch& try_catch) {
Local<Value> exception = try_catch.Exception();

if (!exception->IsObject())
return;

Local<Object> err_obj = exception.As<Object>();

if (IsExceptionDecorated(env, err_obj))
return;

AppendExceptionLine(env, exception, try_catch.Message());
Local<Value> stack = err_obj->Get(env->stack_string());
Local<Value> arrow = err_obj->GetHiddenValue(env->arrow_message_string());

if (!(stack->IsString() && arrow->IsString()))
return;

Local<String> decorated_stack = String::Concat(arrow.As<String>(),
stack.As<String>());
err_obj->Set(env->stack_string(), decorated_stack);
err_obj->SetHiddenValue(env->decorated_string(), True(env->isolate()));
}

static int64_t GetTimeoutArg(const FunctionCallbackInfo<Value>& args,
const int i) {
if (args[i]->IsUndefined() || args[i]->IsString()) {
Expand Down Expand Up @@ -816,7 +840,7 @@ class ContextifyScript : public BaseObject {
if (result.IsEmpty()) {
// Error occurred during execution of the script.
if (display_errors) {
AppendExceptionLine(env, try_catch.Exception(), try_catch.Message());
DecorateErrorStack(env, try_catch);
}
try_catch.ReThrow();
return false;
Expand Down
2 changes: 2 additions & 0 deletions src/node_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ inline static int snprintf(char *buffer, size_t n, const char *format, ...) {
# define NO_RETURN
#endif

bool IsExceptionDecorated(Environment* env, v8::Local<v8::Value> er);

void AppendExceptionLine(Environment* env,
v8::Local<v8::Value> er,
v8::Local<v8::Message> message);
Expand Down
6 changes: 6 additions & 0 deletions test/message/vm_display_syntax_error.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ var vm = require('vm');

console.error('beginning');

try {
vm.runInThisContext('var 4;', { filename: 'foo.vm', displayErrors: true });
} catch (err) {
console.error(err.stack);
}

vm.runInThisContext('var 5;', { filename: 'test.vm' });

console.error('end');
13 changes: 13 additions & 0 deletions test/message/vm_display_syntax_error.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
beginning

foo.vm:1
var 4;
^
SyntaxError: Unexpected number
at Object.exports.runInThisContext (vm.js:*)
at Object.<anonymous> (*test*message*vm_display_syntax_error.js:*)
at Module._compile (module.js:*)
at Object.Module._extensions..js (module.js:*)
at Module.load (module.js:*)
at Function.Module._load (module.js:*)
at Function.Module.runMain (module.js:*)
at startup (node.js:*)
at node.js:*
test.vm:1
var 5;
^
Expand Down