philosopher
philosopher

Reputation: 1151

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

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?

Upvotes: 3

Views: 6898

Answers (4)

John Tribe
John Tribe

Reputation: 1622

It is easy. Use 'error' event :

GIVEN:

const EventEmitter = require('events')

const eventEmitter = new EventEmitter({ captureRejections: true });
eventEmitter.on('callSyncFunction', ()=>{
    throw new Error('Sync function error')
})
eventEmitter.on('callAsyncFunction', async ()=>{
    throw new Error('Async function error')
})

GIVEN: Error handling

eventEmitter.on('error', (e)=>{
    console.log("Error caught: ", e.message)
})

WHEN

eventEmitter.emit('callSyncFunction', {})
eventEmitter.emit('callAsyncFunction',{})

THEN

Expect console output:

Error caught: Sync function error
Error caught: Async function error

Upvotes: 0

Ahmed Magdy
Ahmed Magdy

Reputation: 1226

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)
    })
}

Upvotes: 1

Dmitriy Mozgovoy
Dmitriy Mozgovoy

Reputation: 1597

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

Upvotes: 4

philosopher
philosopher

Reputation: 1151

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

Upvotes: 0

Related Questions