From 455e6f1dd88dc43b9e6d95fadb24c2cad3798ac7 Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Sun, 5 Mar 2017 21:57:02 -0800 Subject: [PATCH] util: throw toJSON errors when formatting %j MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously all errors resulting from JSON.stringify were treated as a proof for circularity of the object structure. That is not the case if the `toJSON` method of the object throws an error. Explicitly check for the exact error message when determining the object structure's cyclicity. PR-URL: https://github.com/nodejs/node/pull/11708 Reviewed-By: Luigi Pinca Reviewed-By: Anna Henningsen Reviewed-By: Sakthipriyan Vairamani Reviewed-By: Michaƫl Zasso Reviewed-By: Colin Ihrig --- lib/util.js | 8 ++++++-- test/parallel/test-util-format.js | 10 ++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/util.js b/lib/util.js index 8048caecba00ed..31761f0dd35545 100644 --- a/lib/util.js +++ b/lib/util.js @@ -38,13 +38,17 @@ const inspectDefaultOptions = Object.seal({ breakLength: 60 }); +const CIRCULAR_ERROR_MESSAGE = 'Converting circular structure to JSON'; + var Debug; function tryStringify(arg) { try { return JSON.stringify(arg); - } catch (_) { - return '[Circular]'; + } catch (err) { + if (err.name === 'TypeError' && err.message === CIRCULAR_ERROR_MESSAGE) + return '[Circular]'; + throw err; } } diff --git a/test/parallel/test-util-format.js b/test/parallel/test-util-format.js index 49b234e2e2bbf7..a57a8094ac05ba 100644 --- a/test/parallel/test-util-format.js +++ b/test/parallel/test-util-format.js @@ -86,6 +86,16 @@ assert.strictEqual(util.format('o: %j, a: %j'), 'o: %j, a: %j'); assert.strictEqual(util.format('%j', o), '[Circular]'); } +{ + const o = { + toJSON() { + throw new Error('Not a circular object but still not serializable'); + } + }; + assert.throws(() => util.format('%j', o), + /^Error: Not a circular object but still not serializable$/); +} + // Errors const err = new Error('foo'); assert.strictEqual(util.format(err), err.stack);