Cleaner code
for async/await error handling with Promise catch handler.
From what I see, this has been a long-standing problem that has bugged (both meanings) many programmers and their code.
ES6 Promise's catch handler provides a proper solution:
this.User.create(userInfo).then(createdUser => {
console.log(createdUser)
// business
// logic
// goes
// here
}).catch(err => {
//handle the error
})
But that looks like a removal of async/await altogether. Not true.
The idea is to use Promise style and catch for top level caller. Otherwise, continue to use async/await.
Example, besides creating user (this.User.create), we can push notification (this.pushNotification) and send email (this.sendEmail). All are async operations. There are no catch handlers required. Just async/await.
this.User.create
this.User.create = async(userInfo) => {
// collect some fb data and do some background check in parallel
const facebookDetails = await retrieveFacebookAsync(userInfo.email)
const backgroundCheck = await backgroundCheckAsync(userInfo.passportID)
if (backgroundCheck.pass !== true) throw Error('Background check failed')
// now we can insert everything
const createdUser = await Database.insert({ ...userInfo, ...facebookDetails })
return createdUser
}
this.pushNotifcation and this.sendEmail
this.pushNotification = async(userInfo) => {
const pushed = await PushNotificationProvider.send(userInfo)
return pushed
})
this.sendEmail = async(userInfo) => {
const sent = await mail({ to: userInfo.email, message: 'Welcome' })
return sent
})
When all the async operations are composed together, we can use Promise-style with a #catch handler attached:
this.User.create(userInfo).then(createdUser => {
console.log(createdUser)
// business logic here
return Promise.all([
this.pushNotification(userInfo),
this.sendEmail(userInfo)
])
}).catch(err => {
// handle err
})
If we were to do this with try/catch, one will have to wrap everything in try/catch (not advisable), or set up many try/catches:
var createdUser
try {
createdUser = await this.User.create(userInfo)
} catch (err) {
//handle err
}
console.log(createdUser)
// business logic here
if (createdUser) {
try {
await this.pushNotification(userInfo)
await this.sendEmail(userInfo)
} catch (err) {
// handle err
}
}