diff --git a/doc/api/util.markdown b/doc/api/util.markdown index a1bfdb0f69e..88ef5eae030 100644 --- a/doc/api/util.markdown +++ b/doc/api/util.markdown @@ -53,7 +53,8 @@ argument. Supported placeholders are: * `%s` - String. * `%d` - Number (both integer and float). -* `%j` - JSON. +* `%j` - JSON. Replaced with the string `'[Circular]'` if the argument + contains circular references. * `%%` - single percent sign (`'%'`). This does not consume an argument. If the placeholder does not have a corresponding argument, the placeholder is diff --git a/lib/util.js b/lib/util.js index 993e3632e5b..23de9df84b6 100644 --- a/lib/util.js +++ b/lib/util.js @@ -38,7 +38,12 @@ exports.format = function(f) { switch (x) { case '%s': return String(args[i++]); case '%d': return Number(args[i++]); - case '%j': return JSON.stringify(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } default: return x; } diff --git a/test/simple/test-util-format.js b/test/simple/test-util-format.js index b5592203a39..ee96744848a 100644 --- a/test/simple/test-util-format.js +++ b/test/simple/test-util-format.js @@ -60,3 +60,9 @@ assert.equal(util.format('%s:%s', 'foo', 'bar'), 'foo:bar'); assert.equal(util.format('%s:%s', 'foo', 'bar', 'baz'), 'foo:bar baz'); assert.equal(util.format('%%%s%%', 'hi'), '%hi%'); assert.equal(util.format('%%%s%%%%', 'hi'), '%hi%%'); + +(function() { + var o = {}; + o.o = o; + assert.equal(util.format('%j', o), '[Circular]'); +})();