Skip to content

Commit

Permalink
util: runtime deprecation for custom .inspect()
Browse files Browse the repository at this point in the history
Change documentation-only deprecation for custom inspection using
`object.inspect` property to a runtime deprecation.

This is a breaking change. Custom inspection via `object.inspect` is
deprecated because there is a more robust Symbol-based alternative to
`.inspect` and the custom inspection via `object.inspect` feature means
that people can accidentally break `console.log()` simply by attaching a
`.inspect` property to their objects. Note that since this is a
deprecation, the custom inspection will still work. The breaking change
is simply the printing of a warning which could alarm users, break tests
or other things that might be dependent on specific output, etc.

PR-URL: #16393
Ref: #15549
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
  • Loading branch information
Trott committed Nov 17, 2017
1 parent 07d39a2 commit 617e3e9
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 5 deletions.
2 changes: 1 addition & 1 deletion doc/api/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,7 @@ Type: Runtime
<a id="DEP0079"></a>
### DEP0079: Custom inspection function on Objects via .inspect()
Type: Documentation-only
Type: Runtime
Using a property named `inspect` on an object to specify a custom inspection
function for [`util.inspect()`][] is deprecated. Use [`util.inspect.custom`][]
Expand Down
1 change: 1 addition & 0 deletions doc/api/util.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ environment variable. For example: `NODE_DEBUG=fs,net,tls`.
added: v0.8.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/16393
description: Deprecation warnings are only emitted once for each code.
-->

Expand Down
17 changes: 13 additions & 4 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -428,14 +428,23 @@ function formatValue(ctx, value, recurseTimes, ln) {
// Provide a hook for user-specified inspect functions.
// Check that value is an object with an inspect function on it
if (ctx.customInspect) {
const maybeCustomInspect = value[customInspectSymbol] || value.inspect;
let maybeCustom = value[customInspectSymbol];

if (!maybeCustom && value.inspect !== exports.inspect &&
typeof value.inspect === 'function') {
maybeCustom = deprecate(
value.inspect,
'Custom inspection function on Objects via .inspect() is deprecated',
'DEP0079'
);
}

if (typeof maybeCustomInspect === 'function' &&
if (typeof maybeCustom === 'function' &&
// Filter out the util module, its inspect function is special
maybeCustomInspect !== exports.inspect &&
maybeCustom !== exports.inspect &&
// Also filter out any prototype objects using the circular check.
!(value.constructor && value.constructor.prototype === value)) {
const ret = maybeCustomInspect.call(value, recurseTimes, ctx);
const ret = maybeCustom.call(value, recurseTimes, ctx);

// If the custom inspection method returned `this`, don't go into
// infinite recursion.
Expand Down
18 changes: 18 additions & 0 deletions test/parallel/test-util-inspect-deprecated.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';
const common = require('../common');

// Test that deprecation warning for custom inspection via the `.inspect()`
// property (on the target object) is emitted once and only once.

const util = require('util');

{
const target = { inspect: () => 'Fhqwhgads' };
// `common.expectWarning` will expect the warning exactly one time only
common.expectWarning(
'DeprecationWarning',
'Custom inspection function on Objects via .inspect() is deprecated'
);
util.inspect(target); // should emit deprecation warning
util.inspect(target); // should not emit deprecation warning
}
6 changes: 6 additions & 0 deletions test/parallel/test-util-inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -1150,3 +1150,9 @@ if (typeof Symbol !== 'undefined') {
}

assert.doesNotThrow(() => util.inspect(process));

// Setting custom inspect property to a non-function should do nothing.
{
const obj = { inspect: 'fhqwhgads' };
assert.strictEqual(util.inspect(obj), "{ inspect: 'fhqwhgads' }");
}

0 comments on commit 617e3e9

Please sign in to comment.