Promise#catch registers a handler for a rejected promise. In a fluent chain, rejection skips the remaining success handlers and reaches catch, allowing the chain to report the error or recover with a replacement value. section 8.2.3 section 8.2.2
Use Promise#catch to keep asynchronous work connected and make failure behavior explicit:
- Place catch after the handlers whose failures it should handle; a thrown error prevents later success handlers from running. section 8.2.3
- Return a fallback value from catch to recover the chain; the returned value becomes the fulfillment value for subsequent handlers. section 8.2.3
- Return nested promises from handlers so their results and errors rejoin the main chain and remain catchable. section 8.2.3
- Handle rejected promises deliberately because an unhandled rejection can produce a runtime warning and may terminate a Node.js process with a non-zero exit code. section 8.2.3
Recovering from a failed chain
Promise.resolve('aabbcc') .then(unique) .then(() => { throw new Error('Ooops!') }) .then(join) .then(toUpper) .catch(({message}) => console.error(message)); The rejection bypasses join and toUpper, then reaches catch. A catch handler can instead return a value such as 'ERROR', allowing later handlers to continue with that recovered value. section 8.2.3
Listing 8.10 Recovering from an error with a default value
Promise.resolve('aabbcc')
.then(unique)
.then(data => #1
Promise.resolve(data)
.then(join)
.then(() => throw new Error('Inside Ooops!'))
.catch(error => {
console.error(`Catch inside: ${error.message}`)
return 'ERROR'
})
)
.then(toUpper)
.then(::console.log)
.catch(({message}) => console.error(message));
Inspect a nested chain that catches an internal error, returns a default value, and continues through later transformations. section 8.2.3
