svrooij / node-sonos-ts

:speaker: Sonos control library, use this library in your own appliction.
https://sonos-ts.svrooij.io/
MIT License
84 stars 18 forks source link

Question - unhandled promise rejection in .on callback function #105

Closed hklages closed 3 years ago

hklages commented 3 years ago

Is there any other way / good practice to handle promise rejections inside event emitter function? I would like to get rid of the try..catch. But when removing them, the unhandled promise rejections are not given back to the calling asyncSubscribeToMultipleEvents.

Currently I call a wrapper asyncSubscribeToMultipleEvents to subscribe

/// async wrapper, status and error handling
    asyncSubscribeToMultipleEvents(node, subscriptions, player)
      .then((success) => {
        node.status({ fill: 'green', shape: 'ring', text: 'connected' })
        node.debug(`success >>${JSON.stringify(success)}`)  
      })
      .catch((error) => {
        node.status({ fill: 'red', shape: 'ring', text: 'disconnected' })
        node.debug(`error >>${JSON.stringify(error, Object.getOwnPropertyNames(error))}`)
      })
....
}

and then

async function asyncSubscribeToMultipleEvents (node, subscriptions, player) {

    async function sendAlarmClockMessage (raw) {
      try {
        debug('new AlarmClockService event >>', JSON.stringify(raw))
        const alarms = await player.AlarmClockService.ListAndParseAlarms()
        const payload = raw
        const topic = `household/${player.host}/alarmClock/alarmList`
        const msg = [null, null, null, null, null]
        msg[1] = { payload, alarms, topic }
        node.send(msg)  
      } catch (error) {
        node.status({ fill: 'red', shape: 'circle', text: 'error' })
        // eslint-disable-next-line max-len
        node.debug(`error during execution of event >>${JSON.stringify(error, Object.getOwnPropertyNames(error))}`)
      }
    }

    // bind events
    if (subscriptions.alarmList) {
      await player.AlarmClockService.Events.on('serviceEvent', sendAlarmClockMessage)
      debug('subscribed to AlarmClockService')
    }
...
}
svrooij commented 3 years ago

You can also add .catch((err)=> console.warn(err)) that will make sure it won’t error out.

hklages commented 3 years ago

I was not precise enough. What I meant: Is there a way to hand over a rejected promise to the routine where the event handler is set up. The try/catch or .catch() - if there are only a few critical command - are ok. So we can close this.