diff --git a/AUTHORS b/AUTHORS index 01bf371..bc8fc52 100644 --- a/AUTHORS +++ b/AUTHORS @@ -19,3 +19,4 @@ Mihai Tomescu (https://github.com/matomesc) Daniel Juhl (https://github.com/danieljuhl) Chris Barber (https://github.com/cb1kenobi) Manuel Schneider (https://github.com/manuelschneider) +Martin Gausby (https://github.com/gausby) diff --git a/CHANGES.md b/CHANGES.md index bd4e8c0..5fbe27b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,7 +8,9 @@ Known issues: ## bunyan 1.3.2 (not yet released) -(nothing yet) +- [pull #182] Fallback to using the optional 'safe-json-stringify' module + if `JSON.stringify` throws -- possibly with an enumerable property + getter than throws. By Martin Gausby. ## bunyan 1.3.1 diff --git a/lib/bunyan.js b/lib/bunyan.js index f305684..0e34970 100644 --- a/lib/bunyan.js +++ b/lib/bunyan.js @@ -43,6 +43,9 @@ try { } catch (e) { safeJsonStringify = null; } +if (process.env.BUNYAN_TEST_NO_SAFE_JSON_STRINGIFY) { + safeJsonStringify = null; +} // The 'mv' module is required for rotating-file stream support. try { @@ -157,11 +160,16 @@ function getCaller3Info() { } +function _indent(s, indent) { + if (!indent) indent = ' '; + var lines = s.split(/\r?\n/g); + return indent + lines.join('\n' + indent); +} + + /** * Warn about an bunyan processing error. * - * If file/line are given, this makes an attempt to warn on stderr only once. - * * @param msg {String} Message with which to warn. * @param dedupKey {String} Optional. A short string key for this warning to * have its warning only printed once. @@ -822,17 +830,19 @@ Logger.prototype._emit = function (rec, noemit) { if (noemit || this.haveNonRawStreams) { try { str = JSON.stringify(rec, safeCycles()) + '\n'; - } - catch(err) { + } catch (e) { if (safeJsonStringify) { str = safeJsonStringify(rec) + '\n'; - } - else { - str = '(Could not JSON stringify data. See stderr for details.)'; - _warn(format('bunyan: ERROR: Could not JSON stringify a property. ' - + 'Please consider installing safe-json-stringify for more ' - + 'information. Stack trace: %s' - , err.stack)); + } else { + var dedupKey = e.stack.split(/\n/g, 2).join('\n'); + _warn('bunyan: ERROR: Exception in ' + + '`JSON.stringify(rec)`. You can install the ' + + '"safe-json-stringify" module to have Bunyan fallback ' + + 'to safer stringification. Record:\n' + + _indent(format('%s\n%s', util.inspect(rec), e.stack)), + dedupKey); + str = format('(Exception in JSON.stringify(rec): %j. ' + + 'See stderr for details.)\n', e.message); } } } diff --git a/package.json b/package.json index e120163..9b64f59 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "optionalDependencies": { "dtrace-provider": "~0.3 >0.3.0", "mv": "~2", - "safe-json-stringify": "1.0.1" + "safe-json-stringify": "~1" }, "devDependencies": { "nodeunit": "0.9.*", diff --git a/test/safe-json-stringify-1.js b/test/safe-json-stringify-1.js index 04c8edf..ba47a2e 100644 --- a/test/safe-json-stringify-1.js +++ b/test/safe-json-stringify-1.js @@ -6,6 +6,5 @@ var log = bunyan.createLogger({ var obj = {}; obj.__defineGetter__('boom', - function() { throw new Error('__defineGetter__ ouch!'); }); + function () { throw new Error('__defineGetter__ ouch!'); }); log.info({obj: obj}, 'using __defineGetter__'); - diff --git a/test/safe-json-stringify-2.js b/test/safe-json-stringify-2.js index 79c1ca7..8910418 100644 --- a/test/safe-json-stringify-2.js +++ b/test/safe-json-stringify-2.js @@ -7,5 +7,5 @@ var log = bunyan.createLogger({ var obj = {}; obj.__defineGetter__('boom', - function() { throw new Error('__defineGetter__ ouch!'); }); + function () { throw new Error('__defineGetter__ ouch!'); }); log.info({obj: obj}, 'using __defineGetter__'); diff --git a/test/safe-json-stringify-3.js b/test/safe-json-stringify-3.js index 87bf120..d2429f8 100644 --- a/test/safe-json-stringify-3.js +++ b/test/safe-json-stringify-3.js @@ -7,7 +7,7 @@ var log = bunyan.createLogger({ // And using `Object.defineProperty`. var obj = {}; Object.defineProperty(obj, 'boom', { - get: function() { throw new Error('defineProperty ouch!'); }, + get: function () { throw new Error('defineProperty ouch!'); }, enumerable: true // enumerable is false by default }); // Twice to test the 'warnKey' usage. diff --git a/test/safe-json-stringify-4.js b/test/safe-json-stringify-4.js index 85f94d4..9e71139 100644 --- a/test/safe-json-stringify-4.js +++ b/test/safe-json-stringify-4.js @@ -8,7 +8,7 @@ var log = bunyan.createLogger({ // And using `Object.defineProperty`. var obj = {}; Object.defineProperty(obj, 'boom', { - get: function() { throw new Error('defineProperty ouch!'); }, + get: function () { throw new Error('defineProperty ouch!'); }, enumerable: true // enumerable is false by default }); // Twice to test the 'warnKey' usage. diff --git a/test/safe-json-stringify.test.js b/test/safe-json-stringify.test.js index 918f20d..1ac41b1 100644 --- a/test/safe-json-stringify.test.js +++ b/test/safe-json-stringify.test.js @@ -62,6 +62,7 @@ test('defineProperty boom, without safe-json-stringify', function (t) { t.ok(stderr.indexOf( 'You can install the "safe-json-stringify" module') !== -1); t.equal(stderr.match( + /* JSSTYLED */ /You can install the "safe-json-stringify" module/g).length, 1); t.end(); });