Using one try/catch block containing multiple await
operations is fine when waiting for promises created on the right hand side of the await
unary operator:
The await
operator stores its parent async
functions’ execution context and returns to the event loop. Execution of the await
operator resumes when it is called back with the settled state and value of its operand.
Upon resumption, await
restores the previously saved execution context and returns the operand promise’s fulfilled value as the result of the await
expression, or throws the rejection reason of a rejected operand.
The try/catch
block invocation is part of the execution context both before and after being saved and restored. Hence multiple await
operations do not disturb the behavior of an outer try
block they share. The catch
block will be invoked with the rejection reason of any promise awaited in the try
block that is rejected.
Uncaught Rejection warning
If code await
s promises that were not created by the await
operator’s argument expression, and don’t have a rejection handler, the promises won’t have a rejection handler before the await
operator applied to them is executed at runtime.
If the try/catch block is triggered before await
adds a handler to such promises, and they reject, an uncaught rejection error occurs. Thanks to @EyolRoth for this caveat, Please see his answer for a case example.
Recommendation: consider carefully if you need to await a promise that was created earlier and doesn’t have an error handler. Then examine
- how its creation could be moved to the
await
‘s operand expression, or - synchronously add a rejection handler to it when first created, or
- defeat it’s uncaught promise detection, which I previously posted in answer to How to handle an unhandled promise rejection asynchronously?