Skip to content

Commit cbec3ee

Browse files
committed
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 3beae2c commit cbec3ee

File tree

4 files changed

+57
-19
lines changed

4 files changed

+57
-19
lines changed

src/env.h

Lines changed: 1 addition & 0 deletions
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

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,16 +1414,7 @@ void AppendExceptionLine(Environment* env,
14141414
if (arrow_str.IsEmpty() || err_obj.IsEmpty() || !err_obj->IsNativeError())
14151415
goto print;
14161416

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

14291420
print:
@@ -1443,17 +1434,27 @@ static void ReportException(Environment* env,
14431434
AppendExceptionLine(env, er, message);
14441435

14451436
Local<Value> trace_value;
1437+
Local<Value> arrow;
14461438

1447-
if (er->IsUndefined() || er->IsNull())
1439+
if (er->IsUndefined() || er->IsNull()) {
14481440
trace_value = Undefined(env->isolate());
1449-
else
1450-
trace_value = er->ToObject(env->isolate())->Get(env->stack_string());
1441+
} else {
1442+
Local<Object> err_obj = er->ToObject(env->isolate());
1443+
1444+
trace_value = err_obj->Get(env->stack_string());
1445+
arrow = err_obj->GetHiddenValue(env->arrow_message_string());
1446+
}
14511447

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

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

Lines changed: 26 additions & 0 deletions
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

Lines changed: 4 additions & 4 deletions
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)