Problem

Raygun is the best tool for catching and resolving bugs before they crash prod. We use it at ui.dev and it’s genuinely really helpful.

function eventuallyFail (time) {
  setTimeout(() => {
    throw Error("Oops!")
  }, time)
}

try {
  eventuallyFail(1000)
} catch (error) {
  console.error(error.message)
}
Solution
function eventuallyFail (time) {
  setTimeout(() => {
    throw Error("Oops!")
  }, time)
}

try {
  eventuallyFail(1000)
} catch (error) {
  console.error(error.message)
}

try/catch is synchronous. By the time our error is thrown, the try/catch block will be long gone - leaving us with Uncaught Error: Oops!. To fix this, we want to rely on promises which allow us more async control.

function eventuallyFail (time) {
  return new Promise((res, rej) => {
    setTimeout(() => {
      rej(Error("Oops!"))
    }, time)
  })
}

eventuallyFail(1000)
  .catch((reason) => console.error(reason.message))