1

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?

Sasgorilla
  • 2,403
  • 2
  • 29
  • 56

0 Answers0