diff --git a/CHANGES.md b/CHANGES.md index 85ca6a0..d22ebd6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,10 @@ ## bunyan 0.14.3 (not yet released) -(nothing yet) +- Improve error serialization to walk the chain of `.cause()` errors + from the likes of `WError` or `VError` error classes from the likes of + [verror](https://github.com/davepacheco/node-verror) and + [restify v2.0](https://github.com/mcavage/node-restify). ## bunyan 0.14.2 diff --git a/lib/bunyan.js b/lib/bunyan.js index a64d569..c2baeed 100644 --- a/lib/bunyan.js +++ b/lib/bunyan.js @@ -987,6 +987,24 @@ Logger.stdSerializers.res = function res(res) { } }; + +/* + * This function dumps long stack traces for exceptions having a cause() + * method. The error classes from + * [verror](https://github.com/davepacheco/node-verror) and + * [restify v2.0](https://github.com/mcavage/node-restify) are examples. + * + * Based on `dumpException` in + * https://github.com/davepacheco/node-extsprintf/blob/master/lib/extsprintf.js + */ +function getFullErrorStack(ex) +{ + var ret = ex.stack || ex.toString(); + if (ex.cause && typeof(ex.cause) === 'function') + ret += '\nCaused by: ' + getFullErrorStack(ex); + return (ret); +} + // Serialize an Error object // (Core error properties are enumerable in node 0.4, not in 0.6). var errSerializer = Logger.stdSerializers.err = function err(err) { @@ -995,7 +1013,7 @@ var errSerializer = Logger.stdSerializers.err = function err(err) { var obj = { message: err.message, name: err.name, - stack: err.stack + stack: getFullErrorStack(err) } Object.keys(err).forEach(function (k) { if (err[k] !== undefined) { @@ -1005,6 +1023,7 @@ var errSerializer = Logger.stdSerializers.err = function err(err) { return obj; }; + // A JSON stringifier that handles cycles safely. // Usage: JSON.stringify(obj, safeCycles()) function safeCycles() {