pino icon indicating copy to clipboard operation
pino copied to clipboard

Unclear how an error is received from worker transport

Open jsumners opened this issue 3 years ago • 3 comments
trafficstars

I'm trying to understand how a worker thread is passing an error back to the main Pino process through the worker message bus. In the code below there is a transport with an internal EventEmitter that emits an unhandled error event. Yet, somehow, we can attach an .on('error') listener to the transport and handle that emitted event. How does this work?

package.json
{
  "dependencies": {
    "pino": "^7.11.0",
    "pino-abstract-transport": "^0.5.0"
  }
}
index.js
'use strict'

const pino = require('pino')
const transport = pino.transport({
  target: './transport.js'
})

// Comment out this listener setup and the script will generate a process
// crash due to an unhandled error event.
transport.on('error', err => {
  console.error('error caught', err)
})

const log = pino(transport)
log.info('hello world')
transport.js
'use strict'

const build = require('pino-abstract-transport')
const {Writable} = require('stream')
const {EventEmitter} = require('events')

module.exports = function (opts) {
  const emitter = new EventEmitter()

  const writeSteam = new Writable({
    objectMode: true
  , autoDestroy: true
  , write(chunk, _, cb) {

    console.log(chunk)
    emitter.emit('error', Error('boom'))

    cb(null)
  }
  })

  return build(function (source) {
    source.pipe(writeSteam),
    {
      close(err, cb) {
        writeSteam.once('close', cb.bind(null, err))
        writeSteam.end()
      }
    }
  })
}

jsumners avatar May 11 '22 17:05 jsumners

The error is catched in:

https://github.com/pinojs/thread-stream/blob/f19ac8dbd602837d2851e17fbc7dfc5bbc51083f/lib/worker.js#L59-L70

and

https://github.com/pinojs/thread-stream/blob/f19ac8dbd602837d2851e17fbc7dfc5bbc51083f/lib/worker.js#L135-L149

Then, it's forwarded to the transport 'error' event in https://github.com/pinojs/thread-stream/blob/f19ac8dbd602837d2851e17fbc7dfc5bbc51083f/index.js#L163-L164

I hope it's clearer.

mcollina avatar May 18 '22 08:05 mcollina

It will be good to document this.

mcollina avatar May 18 '22 08:05 mcollina

Yes, that is very helpful.

jsumners avatar May 18 '22 12:05 jsumners

Hi it seems this is sth I can help with. Lemme take this one.

TommyDew42 avatar Aug 21 '22 17:08 TommyDew42

This is a really fun issue to work with.

One thing I was really confused about was why an error message emitted by an internal EventEmitter will be caught by the process. It turns out the error event actually would be thrown as a normal error to the nodejs program, when we don't have a error listener on an EventEmitter. (reference)

But i guess we shouldn't use this example in our documentation cuz the error message by an internal EventEmitter might confuse people and it is also beyond the scope of discussion.

TommyDew42 avatar Sep 03 '22 09:09 TommyDew42

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

github-actions[bot] avatar Oct 06 '22 00:10 github-actions[bot]