I tried this in a browser and node.js. I get an Uncaught (in promise) Error: here
… I have no idea why the try catch can’t get it.
Anyone can solve this mystery ?
fct = async (msg) => {
throw new Error(msg)
}
delayedValue = (value) => new Promise((resolve) => setTimeout(() => resolve(value), 1000));
(async () => {
try {
console.log(await Promise.all([
fct(await delayedValue('here')),
fct(await delayedValue('it is')),
]));
} catch (e) {
console.error('catched', e);
}
})();
2
Answers
In
fct(await delayedValue('here'))
,await
makes the IIFE wait 1 second fordelayedValue('here')
, which then passes'here'
tofct()
, which in turn throws an error.At this time of the event loop,
await delayedValue('it is')
has yet to return anything, which means the IIFE is still waiting for it and haven’t executecatch
.That being said,
catch
eventually catches the error, but one second late.The problem is the combination of
await
s and un-await
ed async function calls. The code is executed aswhich is a well-known antipattern that causes exactly the problem you are experiencing.
promise1
is a promise that is getting rejected before it gets a handler attached1 viaPromise.all
. It’s already being rejected while thedelayedValue('it is')
promise isawait
ed, and that’s causing an unhandled rejection error.It’s not clear how exactly you wanted the code to run, you might be looking for any of
All of these will fail fast and handle any error from any of the called functions immediately in a surrounding
try
/catch
block.1: More precisely, the handler must be attached "immediately", during the same microtask (loop?), possibly after the promise is rejected – it’s fine when
fct()
returns an already-rejected promise. Either way,await delayedValue()
is not acceptable before the rejection handler is attached.