The following code
const run = async() => {
try {
const p = Promise.reject()
p.catch(() => console.log('exception caught'))
await p
console.log('flow completed')
} catch {
console.log('flow interrupted')
}
}
run()
Prints the following output:
exception caught
flow interrupted
Meaning, even though the catch method is running the exception is not caught
Now if i make this seemingly irrelevant edit and chain the catch right after the promise definition
const run = async() => {
try {
const p = Promise.reject().catch(() => console.log('exception caught'))
await p
console.log('flow completed')
} catch {
console.log('flow interrupted')
}
}
run()
the output becomes
exception caught
flow completed
I tried defining the promise like
const p = new Promise((resolve, reject) => {setTimeout(reject, 100)})
thinking it might matter if the catch was set before the promise rejection but it did not change anything
Im running these tests with node 12.16.1
Can anyone explain why is the exception not caught in the first code sample, but is caught in the second ?
You're forking your chain there. (Wow, that sounds weird…)
You're doing the equivalent of this:
const p = Promise.reject();
p.catch(...);
p.catch(...);
Those are two separate forks in the promise chain which will be caught independently. p
is rejected, p.catch
recovers it for anything that comes after p.catch
. Anything not chained to p.catch
will experience the rejection of p
independently. Since you await p
, you're not in the caught fork of the chain.
p
is rejected and triggers any and all attached catch
handlers, of which there can be more than one. p.catch(...)
on the other hand returns a new successful promise.