Say I have a simple function returning a promise:
function inc(x: number): Promise<number> {
  return new Promise(resolve => resolve(calculateIncrement(x)))
}
function calculateIncrement(x: number): number { 
  if (x > 3) {
    throw new Error(`sorry, ${x} is too big`)
  } else {
    return x + 1
  }
}
If calculateIncrement() throws an error, I can catch that in the normal way with Promise#catch():
>> inc(2).then(y => console.log(`got ${y}`)).catch(e => console.log(`hmmm ... ${e}`))
got 3
>> inc(4).then(y => console.log(`got ${y}`)).catch(e => console.log(`hmmm ... ${e}`))
hmmm ... sorry, 4 is too big
So far so good. Now I want to introduce an arbitrary delay in my promise:
function incWithDelay(x: number, delayInMs: number): Promise<number> {
  return new Promise(resolve =>
    setTimeout(
      () => resolve(calculateIncrement(x)), 
      delayInMs
    )
  )
}
Unfortunately, using setTimeout in this way breaks error-handling:
>> incWithDelay(2, 10).then(y => console.log(`got ${y}`)).catch(e => console.log(`hmmm ... ${e}`))
got 3
>> incWithDelay(3, 10).then(y => console.log(`got ${y}`)).catch(e => console.log(`hmmm ... ${e}`))
Error: sorry, 4 is too big        // <- error is no longer caught here
(This question is possibly related to Using setTimout on a promise chain, but unlike in that example, my incWithDelay function is returning a promise, so I'm not sure why setTimeout breaks catch).
Why can I no longer catch the error?
