Repository: pinojs/pino
Pull request #511 (2018-09-02 22:52:00)

Pass props from error objects to pino-pretty
`pino-pretty` has an [`errorProps`](https://github.com/pinojs/pino-pretty#cli-arguments) option that allows extra props on error objects to be printed. These props weren't being passed to `pino-pretty` so the option did nothing. This PR fixes that.

#### Example

```js
const pino = require('pino')({
  base: {pid: process.pid, hostname: 'my-pc'},
  prettyPrint: {
    errorProps: 'code,errno',
  },
})

const err = new Error('kaboom')
err.code = 'ENOENT'
err.errno = 1

pino.error(err)
```

Output before:

```                                   
[1535928031343] ERROR (15668 on my-pc): kaboom
    Error: kaboom
        at Object.<anonymous> (C:\pino-test\pino-test.js:13:18)
        at Module._compile (internal/modules/cjs/loader.js:689:30)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
        at Module.load (internal/modules/cjs/loader.js:599:32)
        at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
        at Function.Module._load (internal/modules/cjs/loader.js:530:3)
        at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
        at startup (internal/bootstrap/node.js:266:19)
        at bootstrapNodeJSCore (internal/bootstrap/node.js:596:3)
```

Output after:

```                                         
[1535928031343] ERROR (15668 on my-pc): kaboom
    Error: kaboom
        at Object.<anonymous> (C:\pino-test\pino-test.js:13:18)
        at Module._compile (internal/modules/cjs/loader.js:689:30)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
        at Module.load (internal/modules/cjs/loader.js:599:32)
        at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
        at Function.Module._load (internal/modules/cjs/loader.js:530:3)
        at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
        at startup (internal/bootstrap/node.js:266:19)
        at bootstrapNodeJSCore (internal/bootstrap/node.js:596:3)
code: ENOENT
errno: 1
```


Patch:
diff --git a/lib/tools.js b/lib/tools.js
index 6d3c400..439c9f4 100644
--- a/lib/tools.js
+++ b/lib/tools.js
@@ -195,10 +195,11 @@ function prettifierMetaWrapper (pretty, dest) {
 
       var lastObj = this.lastObj
       var msg = this.lastMsg
+      var errorProps = null
 
       if (lastObj instanceof Error) {
         msg = msg || lastObj.message
-        lastObj = {
+        errorProps = {
           type: 'Error',
           stack: lastObj.stack
         }
@@ -208,7 +209,7 @@ function prettifierMetaWrapper (pretty, dest) {
         level: this.lastLevel,
         msg,
         time
-      }, chindings, lastObj)
+      }, chindings, lastObj, errorProps)
 
       const serializers = this.lastLogger[serializersSym]
       const keys = Object.keys(serializers)


Test patch:
diff --git a/test/fixtures/pretty/error-props.js b/test/fixtures/pretty/error-props.js
new file mode 100644
index 0000000..32812cf
--- /dev/null
+++ b/test/fixtures/pretty/error-props.js
@@ -0,0 +1,9 @@
+global.process = { __proto__: process, pid: 123456 }
+Date.now = function () { return 1459875739796 }
+require('os').hostname = function () { return 'abcdefghijklmnopqr' }
+var pino = require(require.resolve('./../../../'))
+var log = pino({
+  prettyPrint: { errorProps: 'code,errno' }
+})
+var err = Object.assign(new Error('kaboom'), { code: 'ENOENT', errno: 1 })
+log.error(err)
diff --git a/test/pretty.test.js b/test/pretty.test.js
index 3cd505e..8905fc2 100644
--- a/test/pretty.test.js
+++ b/test/pretty.test.js
@@ -187,3 +187,18 @@ test('errors', async ({ isNot }) => {
   isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): with a message/), null)
   isNot(actual.match(/.*error\.js.*/), null)
 })
+
+test('errors with props', async ({ isNot }) => {
+  var actual = ''
+  const child = fork(join(__dirname, 'fixtures', 'pretty', 'error-props.js'), { silent: true })
+
+  child.stdout.pipe(writer((s, enc, cb) => {
+    actual += s
+    cb()
+  }))
+  await once(child, 'close')
+  isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): kaboom/), null)
+  isNot(actual.match(/code: ENOENT/), null)
+  isNot(actual.match(/errno: 1/), null)
+  isNot(actual.match(/.*error-props\.js.*/), null)
+})