Skip to content

Commit e2f47f5

Browse files
zeusdeuxjasnell
authored andcommitted
util: Change how Error objects are formatted
Previously, Error objects were formatted as the result of a `toString` call bounded by square brackets. They are now formatted as the stack trace for the given error object. The intention initially was to emulate how browsers do `console.error` but since that would also impact `console.warn`, `console.log`, etc, it was decided to make the change at `util.inspect` level which is in turn used by the `console` package. Fixes: #4452 PR-URL: #4582 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Trevor Norris <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent d157976 commit e2f47f5

File tree

3 files changed

+41
-14
lines changed

3 files changed

+41
-14
lines changed

lib/util.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ function formatPrimitiveNoColor(ctx, value) {
488488

489489

490490
function formatError(value) {
491-
return '[' + Error.prototype.toString.call(value) + ']';
491+
return value.stack || '[' + Error.prototype.toString.call(value) + ']';
492492
}
493493

494494

test/parallel/test-util-format.js

+18-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
'use strict';
22
require('../common');
3-
var assert = require('assert');
4-
var util = require('util');
5-
var symbol = Symbol('foo');
3+
const assert = require('assert');
4+
const util = require('util');
5+
const symbol = Symbol('foo');
66

77
assert.equal(util.format(), '');
88
assert.equal(util.format(''), '');
@@ -55,13 +55,26 @@ assert.equal(util.format('%%%s%%%%', 'hi'), '%hi%%');
5555
})();
5656

5757
// Errors
58-
assert.equal(util.format(new Error('foo')), '[Error: foo]');
58+
const err = new Error('foo');
59+
assert.equal(util.format(err), err.stack);
5960
function CustomError(msg) {
6061
Error.call(this);
6162
Object.defineProperty(this, 'message',
6263
{ value: msg, enumerable: false });
6364
Object.defineProperty(this, 'name',
6465
{ value: 'CustomError', enumerable: false });
66+
Error.captureStackTrace(this, CustomError);
6567
}
6668
util.inherits(CustomError, Error);
67-
assert.equal(util.format(new CustomError('bar')), '[CustomError: bar]');
69+
const customError = new CustomError('bar');
70+
assert.equal(util.format(customError), customError.stack);
71+
// Doesn't capture stack trace
72+
function BadCustomError(msg) {
73+
Error.call(this);
74+
Object.defineProperty(this, 'message',
75+
{ value: msg, enumerable: false });
76+
Object.defineProperty(this, 'name',
77+
{ value: 'BadCustomError', enumerable: false });
78+
}
79+
util.inherits(BadCustomError, Error);
80+
assert.equal(util.format(new BadCustomError('foo')), '[BadCustomError: foo]');

test/parallel/test-util-inspect.js

+22-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22
require('../common');
3-
var assert = require('assert');
4-
var util = require('util');
3+
const assert = require('assert');
4+
const util = require('util');
55
const vm = require('vm');
66

77
assert.equal(util.inspect(1), '1');
@@ -288,19 +288,33 @@ assert.equal(util.inspect(setter, true), '{ [b]: [Setter] }');
288288
assert.equal(util.inspect(getterAndSetter, true), '{ [c]: [Getter/Setter] }');
289289

290290
// exceptions should print the error message, not '{}'
291-
assert.equal(util.inspect(new Error()), '[Error]');
292-
assert.equal(util.inspect(new Error('FAIL')), '[Error: FAIL]');
293-
assert.equal(util.inspect(new TypeError('FAIL')), '[TypeError: FAIL]');
294-
assert.equal(util.inspect(new SyntaxError('FAIL')), '[SyntaxError: FAIL]');
291+
const errors = [];
292+
errors.push(new Error());
293+
errors.push(new Error('FAIL'));
294+
errors.push(new TypeError('FAIL'));
295+
errors.push(new SyntaxError('FAIL'));
296+
errors.forEach(function(err) {
297+
assert.equal(util.inspect(err), err.stack);
298+
});
295299
try {
296300
undef();
297301
} catch (e) {
298-
assert.equal(util.inspect(e), '[ReferenceError: undef is not defined]');
302+
assert.equal(util.inspect(e), e.stack);
299303
}
300304
var ex = util.inspect(new Error('FAIL'), true);
301-
assert.ok(ex.indexOf('[Error: FAIL]') != -1);
305+
assert.ok(ex.indexOf('Error: FAIL') != -1);
302306
assert.ok(ex.indexOf('[stack]') != -1);
303307
assert.ok(ex.indexOf('[message]') != -1);
308+
// Doesn't capture stack trace
309+
function BadCustomError(msg) {
310+
Error.call(this);
311+
Object.defineProperty(this, 'message',
312+
{ value: msg, enumerable: false });
313+
Object.defineProperty(this, 'name',
314+
{ value: 'BadCustomError', enumerable: false });
315+
}
316+
util.inherits(BadCustomError, Error);
317+
assert.equal(util.inspect(new BadCustomError('foo')), '[BadCustomError: foo]');
304318

305319
// GH-1941
306320
// should not throw:

0 commit comments

Comments
 (0)