17

I want to use onerror to intercept and log all errors that occur in my JavaScript application. This works as expected except when using promises or async functions.

In the following snipped the exception thrown by fail is intercepted as expected but rejectPromise and throwAsync instead of invoking the onerror handler always show an Uncaught (in promise) Error in the console?

How can I always intercept all errors in a code base that uses promises and async functions?

window.onerror = function(message, source, lineno, colno, error) {
  console.log('onerror handler logging error', message);
  return true;
}

function rejectPromise() {
  return Promise.reject(new Error('rejected promise'));
}

async function throwAsync() {
  throw new Error('async exception');
}

function fail() {
  throw new Error('exception');
}

rejectPromise().then(() => console.log('success'));
throwAsync();
fail();
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
doberkofler
  • 9,511
  • 18
  • 74
  • 126
  • for that, the Promise have a second Parameter which is the reject Function Handler which can be handled by using .catch() on the Promise. This implies already that a Promise use try/catch – Scriptkiddy1337 Mar 15 '19 at 08:47

2 Answers2

21

You can add a window handler for onunhandledrejection, since unhandled Promise rejections aren't exactly the same things as errors. Check the results of the below snippet in your browser console (not the snippet console, it'll have problems trying to display the big object):

window.onerror = function(message, source, lineno, colno, error) {
  console.log('onerror handler logging error', message);
  return true;
}
window.onunhandledrejection = function(errorEvent) {
  console.log('onunhandledrejection handler logging error', errorEvent);
  return true;
}


function rejectPromise() {
  return Promise.reject(new Error('rejected promise'));
}

async function throwAsync() {
  throw new Error('async exception');
}

function fail() {
  throw new Error('exception');
}

rejectPromise().then(() => console.log('success'));
throwAsync();
fail();
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
3

You can add addEventListener to fix that as throw new Exception() will be raising an error event. So fail() will raise an error event

window.addEventListener("error", function (e) {
   alert("Error occurred: " + e.error.message);
   return false;
})

window.addEventListener('unhandledrejection', function (e) {
  alert("Error occurred: " + e.reason.message);
})

Hope this helps !!

vizsatiz
  • 1,933
  • 1
  • 17
  • 36