From e203c9fa56a21f08f19e5e65317919fc6a5e2015 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Thu, 11 Oct 2012 14:02:48 -0700 Subject: [PATCH] fix long-stack-trace error serialization added in 0.14.4 --- CHANGES.md | 10 ++++- lib/bunyan.js | 8 +++- package.json | 3 +- test/std-serializers.test.js | 86 +++++++++++++++++++++++++++++++++++- 4 files changed, 102 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 844f1a5..fb80332 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,15 @@ ## bunyan 0.14.5 (not yet released) -(nothing yet) +- Fix a bug in the long-stack-trace error serialization added in 0.14.4. The + symptom: + + bunyan@0.14.4: .../node_modules/bunyan/lib/bunyan.js:1002 + var ret = ex.stack || ex.toString(); + ^ + TypeError: Cannot read property 'stack' of undefined + at getFullErrorStack (.../node_modules/bunyan/lib/bunyan.js:1002:15) + ... ## bunyan 0.14.4 diff --git a/lib/bunyan.js b/lib/bunyan.js index 8d1113a..7846abb 100644 --- a/lib/bunyan.js +++ b/lib/bunyan.js @@ -1000,8 +1000,12 @@ Logger.stdSerializers.res = function res(res) { function getFullErrorStack(ex) { var ret = ex.stack || ex.toString(); - if (ex.cause && typeof(ex.cause) === 'function') - ret += '\nCaused by: ' + getFullErrorStack(ex.cause()); + if (ex.cause && typeof(ex.cause) === 'function') { + var cex = ex.cause(); + if (cex) { + ret += '\nCaused by: ' + getFullErrorStack(cex); + } + } return (ret); } diff --git a/package.json b/package.json index 184e44b..ac3b78b 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "devDependencies": { "tap": "0.2.0", - "ben": "0.0.0" + "ben": "0.0.0", + "verror": "1.3.3" }, "scripts": { diff --git a/test/std-serializers.test.js b/test/std-serializers.test.js index 132bb4f..5ab13a7 100644 --- a/test/std-serializers.test.js +++ b/test/std-serializers.test.js @@ -5,9 +5,11 @@ */ var test = require('tap').test; -var bunyan = require('../lib/bunyan'); var http = require('http'); +var bunyan = require('../lib/bunyan'); +var verror = require('verror'); + function CapturingStream(recs) { this.recs = recs; @@ -168,3 +170,85 @@ test('err serializer', function (t) { t.equal(lastRecord.err.stack, theErr.stack); t.end(); }); + + +test('err serializer: long stack', function (t) { + var records = []; + var log = bunyan.createLogger({ + name: 'serializer-test', + streams: [{ + stream: new CapturingStream(records), + type: 'raw' + }], + serializers: { + err: bunyan.stdSerializers.err + } + }); + + var topErr, midErr, bottomErr; + + // Just a VError. + topErr = new verror.VError('top err'); + log.info(topErr, 'the error'); + var lastRecord = records[records.length-1]; + t.equal(lastRecord.err.message, topErr.message); + t.equal(lastRecord.err.name, topErr.name); + t.equal(lastRecord.err.stack, topErr.stack); + + // Just a WError. + topErr = new verror.WError('top err'); + log.info(topErr, 'the error'); + var lastRecord = records[records.length-1]; + t.equal(lastRecord.err.message, topErr.message); + t.equal(lastRecord.err.name, topErr.name); + t.equal(lastRecord.err.stack, topErr.stack); + + // WError <- TypeError + bottomErr = new TypeError('bottom err'); + topErr = new verror.WError(bottomErr, 'top err'); + log.info(topErr, 'the error'); + var lastRecord = records[records.length-1]; + t.equal(lastRecord.err.message, topErr.message); + t.equal(lastRecord.err.name, topErr.name); + var expectedStack = topErr.stack + '\nCaused by: ' + bottomErr.stack; + t.equal(lastRecord.err.stack, expectedStack); + + // WError <- WError + bottomErr = new verror.WError('bottom err'); + topErr = new verror.WError(bottomErr, 'top err'); + log.info(topErr, 'the error'); + var lastRecord = records[records.length-1]; + t.equal(lastRecord.err.message, topErr.message); + t.equal(lastRecord.err.name, topErr.name); + var expectedStack = topErr.stack + '\nCaused by: ' + bottomErr.stack; + t.equal(lastRecord.err.stack, expectedStack); + + // WError <- WError <- TypeError + bottomErr = new TypeError('bottom err'); + midErr = new verror.WError(bottomErr, 'mid err'); + topErr = new verror.WError(midErr, 'top err'); + log.info(topErr, 'the error'); + var lastRecord = records[records.length-1]; + t.equal(lastRecord.err.message, topErr.message); + t.equal(lastRecord.err.name, topErr.name); + var expectedStack = (topErr.stack + + '\nCaused by: ' + midErr.stack + + '\nCaused by: ' + bottomErr.stack); + t.equal(lastRecord.err.stack, expectedStack); + + // WError <- WError <- WError + bottomErr = new verror.WError('bottom err'); + midErr = new verror.WError(bottomErr, 'mid err'); + topErr = new verror.WError(midErr, 'top err'); + log.info(topErr, 'the error'); + var lastRecord = records[records.length-1]; + t.equal(lastRecord.err.message, topErr.message); + t.equal(lastRecord.err.name, topErr.name); + var expectedStack = (topErr.stack + + '\nCaused by: ' + midErr.stack + + '\nCaused by: ' + bottomErr.stack); + t.equal(lastRecord.err.stack, expectedStack); + + + t.end(); +});