Skip to content

Commit ef65321

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 9d34bd1 commit ef65321

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
@@ -1413,16 +1413,7 @@ void AppendExceptionLine(Environment* env,
14131413
if (arrow_str.IsEmpty() || err_obj.IsEmpty() || !err_obj->IsNativeError())
14141414
goto print;
14151415

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

14281419
print:
@@ -1442,17 +1433,27 @@ static void ReportException(Environment* env,
14421433
AppendExceptionLine(env, er, message);
14431434

14441435
Local<Value> trace_value;
1436+
Local<Value> arrow;
14451437

1446-
if (er->IsUndefined() || er->IsNull())
1438+
if (er->IsUndefined() || er->IsNull()) {
14471439
trace_value = Undefined(env->isolate());
1448-
else
1449-
trace_value = er->ToObject(env->isolate())->Get(env->stack_string());
1440+
} else {
1441+
Local<Object> err_obj = er->ToObject(env->isolate());
1442+
1443+
trace_value = err_obj->Get(env->stack_string());
1444+
arrow = err_obj->GetHiddenValue(env->arrow_message_string());
1445+
}
14501446

14511447
node::Utf8Value trace(env->isolate(), trace_value);
14521448

14531449
// range errors have a trace member set to undefined
14541450
if (trace.length() > 0 && !trace_value->IsUndefined()) {
1455-
fprintf(stderr, "%s\n", *trace);
1451+
if (arrow.IsEmpty() || !arrow->IsString()) {
1452+
fprintf(stderr, "%s\n", *trace);
1453+
} else {
1454+
node::Utf8Value arrow_string(env->isolate(), arrow);
1455+
fprintf(stderr, "%s\n%s\n", *arrow_string, *trace);
1456+
}
14561457
} else {
14571458
// this really only happens for RangeErrors, since they're the only
14581459
// kind that won't have all this info in the trace, or when non-Error
@@ -1476,7 +1477,17 @@ static void ReportException(Environment* env,
14761477
} else {
14771478
node::Utf8Value name_string(env->isolate(), name);
14781479
node::Utf8Value message_string(env->isolate(), message);
1479-
fprintf(stderr, "%s: %s\n", *name_string, *message_string);
1480+
1481+
if (arrow.IsEmpty() || !arrow->IsString()) {
1482+
fprintf(stderr, "%s: %s\n", *name_string, *message_string);
1483+
} else {
1484+
node::Utf8Value arrow_string(env->isolate(), arrow);
1485+
fprintf(stderr,
1486+
"%s\n%s: %s\n",
1487+
*arrow_string,
1488+
*name_string,
1489+
*message_string);
1490+
}
14801491
}
14811492
}
14821493

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)