How to catch an error on an eventEmitter that runs an async function on 'emit'?

Viewed 2668

I am having some trouble catching errors on async functions that are are run by an eventEmitter on emit.

Here is the code:

const EventEmitter = require('events')

const eventEmitter = new EventEmitter()
eventEmitter.addListener('callSyncFunction', syncFunction)
eventEmitter.addListener('callAsyncFunction', asyncFunction)

function syncFunction() {
    throw new Error('Sync function error')
}

async function asyncFunction() {
    throw new Error('Async function error')
}

try {
    eventEmitter.emit('callSyncFunction')
} catch(e) {
    console.log(e)
}
// Works and prints 'Sync function error'

try {
    eventEmitter.emit('callAsyncFunction')
} catch(e) {
    console.log(e)
}
// Does not  work and gives an Unhandled promise rejection

I am able to catch errors when a synchronous function is called by the eventEmitter but unable. to catch errors when async functions are run. As suggested on https://nodejs.org/api/events.html#events_capture_rejections_of_promises I tried enabled captureRejections: true but it still does not help capture those errors.

Apart from using a library like emittery, is there any solution to this?

3 Answers

You can't use nodejs EventEmitter to catch errors from async listeners. The emit method is fully synchronous. Setting capture Rejections: true just allows you to catch async errors through error event. You should use some third-party lib for this, e.g EventEmitter2

Why don't you create a wrapper Listener and resolve the Async function inside it

function WrapperListener(){
    asyncFunction().then(result=>{
            //dosomething
        }).catch(e=>{
           console.log(e)
    })
}

I ended up using this wrapper for my purposes: events-async.

Related