Skip to content

Commit 4b844e6

Browse files
indutnyrvagg
authored andcommitted
node: do not override message/stack of error
Put the `...^` arrow string to the hidden property of the object, and use it only when printing error to the stderr. Fix: #2104 PR-URL: #2108 Reviewed-By: Trevor Norris <[email protected]>
1 parent 4a4775e commit 4b844e6

File tree

4 files changed

+57
-19
lines changed

4 files changed

+57
-19
lines changed

src/env.h

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ namespace node {
4444
V(address_string, "address") \
4545
V(args_string, "args") \
4646
V(argv_string, "argv") \
47+
V(arrow_message_string, "arrowMessage") \
4748
V(async, "async") \
4849
V(async_queue_string, "_asyncQueue") \
4950
V(atime_string, "atime") \

src/node.cc

+26-15
Original file line numberDiff line numberDiff line change
@@ -1415,16 +1415,7 @@ void AppendExceptionLine(Environment* env,
14151415
if (arrow_str.IsEmpty() || err_obj.IsEmpty() || !err_obj->IsNativeError())
14161416
goto print;
14171417

1418-
msg = err_obj->Get(env->message_string());
1419-
stack = err_obj->Get(env->stack_string());
1420-
1421-
if (msg.IsEmpty() || stack.IsEmpty())
1422-
goto print;
1423-
1424-
err_obj->Set(env->message_string(),
1425-
String::Concat(arrow_str, msg->ToString(env->isolate())));
1426-
err_obj->Set(env->stack_string(),
1427-
String::Concat(arrow_str, stack->ToString(env->isolate())));
1418+
err_obj->SetHiddenValue(env->arrow_message_string(), arrow_str);
14281419
return;
14291420

14301421
print:
@@ -1444,17 +1435,27 @@ static void ReportException(Environment* env,
14441435
AppendExceptionLine(env, er, message);
14451436

14461437
Local<Value> trace_value;
1438+
Local<Value> arrow;
14471439

1448-
if (er->IsUndefined() || er->IsNull())
1440+
if (er->IsUndefined() || er->IsNull()) {
14491441
trace_value = Undefined(env->isolate());
1450-
else
1451-
trace_value = er->ToObject(env->isolate())->Get(env->stack_string());
1442+
} else {
1443+
Local<Object> err_obj = er->ToObject(env->isolate());
1444+
1445+
trace_value = err_obj->Get(env->stack_string());
1446+
arrow = err_obj->GetHiddenValue(env->arrow_message_string());
1447+
}
14521448

14531449
node::Utf8Value trace(env->isolate(), trace_value);
14541450

14551451
// range errors have a trace member set to undefined
14561452
if (trace.length() > 0 && !trace_value->IsUndefined()) {
1457-
fprintf(stderr, "%s\n", *trace);
1453+
if (arrow.IsEmpty() || !arrow->IsString()) {
1454+
fprintf(stderr, "%s\n", *trace);
1455+
} else {
1456+
node::Utf8Value arrow_string(env->isolate(), arrow);
1457+
fprintf(stderr, "%s\n%s\n", *arrow_string, *trace);
1458+
}
14581459
} else {
14591460
// this really only happens for RangeErrors, since they're the only
14601461
// kind that won't have all this info in the trace, or when non-Error
@@ -1478,7 +1479,17 @@ static void ReportException(Environment* env,
14781479
} else {
14791480
node::Utf8Value name_string(env->isolate(), name);
14801481
node::Utf8Value message_string(env->isolate(), message);
1481-
fprintf(stderr, "%s: %s\n", *name_string, *message_string);
1482+
1483+
if (arrow.IsEmpty() || !arrow->IsString()) {
1484+
fprintf(stderr, "%s: %s\n", *name_string, *message_string);
1485+
} else {
1486+
node::Utf8Value arrow_string(env->isolate(), arrow);
1487+
fprintf(stderr,
1488+
"%s\n%s: %s\n",
1489+
*arrow_string,
1490+
*name_string,
1491+
*message_string);
1492+
}
14821493
}
14831494
}
14841495

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'use strict';
2+
var common = require('../common');
3+
var assert = require('assert');
4+
var child_process = require('child_process');
5+
6+
var p = child_process.spawn(process.execPath, [
7+
'-e',
8+
'vm = require("vm");' +
9+
'context = vm.createContext({});' +
10+
'try { vm.runInContext("throw new Error(\'boo\')", context); } ' +
11+
'catch (e) { console.log(e.message); }'
12+
]);
13+
14+
p.stderr.on('data', function(data) {
15+
assert(false, 'Unexpected stderr data: ' + data);
16+
});
17+
18+
var output = '';
19+
20+
p.stdout.on('data', function(data) {
21+
output += data;
22+
});
23+
24+
process.on('exit', function() {
25+
assert.equal(output.replace(/[\r\n]+/g, ''), 'boo');
26+
});

test/sequential/test-vm-syntax-error-stderr.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,17 @@ var wrong_script = path.join(common.fixturesDir, 'cert.pem');
88

99
var p = child_process.spawn(process.execPath, [
1010
'-e',
11-
'try { require(process.argv[1]); } catch (e) { console.log(e.stack); }',
11+
'require(process.argv[1]);',
1212
wrong_script
1313
]);
1414

15-
p.stderr.on('data', function(data) {
16-
assert(false, 'Unexpected stderr data: ' + data);
15+
p.stdout.on('data', function(data) {
16+
assert(false, 'Unexpected stdout data: ' + data);
1717
});
1818

1919
var output = '';
2020

21-
p.stdout.on('data', function(data) {
21+
p.stderr.on('data', function(data) {
2222
output += data;
2323
});
2424

0 commit comments

Comments
 (0)