Skip to content

Commit

Permalink
util: Change how Error objects are formatted
Browse files Browse the repository at this point in the history
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
  • Loading branch information
zeusdeux committed Jan 8, 2016
1 parent f9f1dd9 commit 006a66a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 14 deletions.
2 changes: 1 addition & 1 deletion lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ function formatPrimitiveNoColor(ctx, value) {


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


Expand Down
23 changes: 18 additions & 5 deletions test/parallel/test-util-format.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use strict';
require('../common');
var assert = require('assert');
var util = require('util');
var symbol = Symbol('foo');
const assert = require('assert');
const util = require('util');
const symbol = Symbol('foo');

assert.equal(util.format(), '');
assert.equal(util.format(''), '');
Expand Down Expand Up @@ -55,13 +55,26 @@ assert.equal(util.format('%%%s%%%%', 'hi'), '%hi%%');
})();

// Errors
assert.equal(util.format(new Error('foo')), '[Error: foo]');
const err = new Error('foo');
assert.equal(util.format(err), err.stack);
function CustomError(msg) {
Error.call(this);
Object.defineProperty(this, 'message',
{ value: msg, enumerable: false });
Object.defineProperty(this, 'name',
{ value: 'CustomError', enumerable: false });
Error.captureStackTrace(this, CustomError);
}
util.inherits(CustomError, Error);
assert.equal(util.format(new CustomError('bar')), '[CustomError: bar]');
const customError = new CustomError('bar');
assert.equal(util.format(customError), customError.stack);
// Doesn't capture stack trace
function BadCustomError(msg) {
Error.call(this);
Object.defineProperty(this, 'message',
{ value: msg, enumerable: false });
Object.defineProperty(this, 'name',
{ value: 'BadCustomError', enumerable: false });
}
util.inherits(BadCustomError, Error);
assert.equal(util.format(new BadCustomError('foo')), '[BadCustomError: foo]');
30 changes: 22 additions & 8 deletions test/parallel/test-util-inspect.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
require('../common');
var assert = require('assert');
var util = require('util');
const assert = require('assert');
const util = require('util');
const vm = require('vm');

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

// exceptions should print the error message, not '{}'
assert.equal(util.inspect(new Error()), '[Error]');
assert.equal(util.inspect(new Error('FAIL')), '[Error: FAIL]');
assert.equal(util.inspect(new TypeError('FAIL')), '[TypeError: FAIL]');
assert.equal(util.inspect(new SyntaxError('FAIL')), '[SyntaxError: FAIL]');
const errors = [];
errors.push(new Error());
errors.push(new Error('FAIL'));
errors.push(new TypeError('FAIL'));
errors.push(new SyntaxError('FAIL'));
errors.forEach(function(err) {
assert.equal(util.inspect(err), err.stack);
});
try {
undef();
} catch (e) {
assert.equal(util.inspect(e), '[ReferenceError: undef is not defined]');
assert.equal(util.inspect(e), e.stack);
}
var ex = util.inspect(new Error('FAIL'), true);
assert.ok(ex.indexOf('[Error: FAIL]') != -1);
assert.ok(ex.indexOf('Error: FAIL') != -1);
assert.ok(ex.indexOf('[stack]') != -1);
assert.ok(ex.indexOf('[message]') != -1);
// Doesn't capture stack trace
function BadCustomError(msg) {
Error.call(this);
Object.defineProperty(this, 'message',
{ value: msg, enumerable: false });
Object.defineProperty(this, 'name',
{ value: 'BadCustomError', enumerable: false });
}
util.inherits(BadCustomError, Error);
assert.equal(util.inspect(new BadCustomError('foo')), '[BadCustomError: foo]');

// GH-1941
// should not throw:
Expand Down

0 comments on commit 006a66a

Please sign in to comment.