New in JavaScript: reportError – a method to report to global event handlers
Tags: javascript
Published: 2022-02-08 13:13:40

---
title: New in JavaScript: reportError – a method to report to global event handlers
published: true
description: Use `reportError` to report errors to global error event handlers.
tags: javascript
canonical_url: https://www.stefanjudis.com/blog/reporterror-a-method-to-report-to-global-event-handlers/
---

If you're a library author, there's always the question of how to implement easy-to-use error handling. You want to make sure that your code is bulletproof and not blowing up in case of an exception, but you want to ensure that errors bubble up to the end-user and their error monitoring, too.

So how do you do this?

Frontend error monitoring usually is based on a global error event handler that's triggered in case of an unhandled exception.

```javascript
window.onerror = function (message, source, lineno, colno, error) {
  console.log("message:" + error.message + ", lineno: " + lineno);
  return true;
};

// Tip: you could also use `addEventListener`
// -> window.addEventListener("error", ...)

function triggerError() {
  throw new Error('Oh no!');
}

triggerError();

// Console output:
// message: Oh no!, lineno: 10
```

This approach works great, but error handling becomes more complicated if you're a few levels deep in your call stack.

Let's look at examples and pretend that you're writing library code that accepts event listeners, which you iterate over eventually.

*The following code snippets run in an environment that defines a `window.error = function () {}` expression such as the one above. This error handler shows up in the included console output.*

Let's iterate over the passed event handlers without any error handling:

```javascript
// Custom event handlers passed by someone else
const fns = [
  () => { console.log("I'm first!"); },
  () => { throw new Error("Oh no!"); },
  () => { console.log("I'm third!"); },
];

// Iterate over the functions
for (const fn of fns) {
  fn();
}

// Output in the console:
// I'm first!
// message: Oh no!, lineno: 10
```

The global error handler is triggered so that your library users can handle and monitor exceptions. That's great, but the thrown exception blows up and stops the loop, too. The third function is not running. 

Let's add exception handling using `try/catch`:

```javascript
// Custom event handlers passed by some one else
const fns = [
  () => { console.log("I'm first!"); },
  () => { throw new Error("Oh no!"); },
  () => { console.log("I'm third!"); },
];

// Iterate over the methods
for (const fn of fns) {
  try {
    fn();
  } catch(error) {
    console.error(error);
  }
}

// Output in the console:
// I'm first!
// Error: Oh no!
// I'm third!
```

The loop succeeds with the added `try/catch` statement, but the error is not bubbling up to the global event handler anymore. How do you pass the exception up the chain then?

There's a hacky way... 🙈

```javascript
for (const fn of fns) {
  try {
    fn();
  } catch (error) {
    // Use setTimeout hack to trigger the global error
    setTimeout(() => {
      throw error;
    }, 0);
  }
}

// Console output:
// I'm first!
// I'm third!
// message: Oh no!, lineno: 24
```

And while using `setTimeout` works, it's not more than a hack. **That's where [`reportError` comes into play](https://developer.mozilla.org/en-US/docs/Web/API/reportError).**

> The `reportError()` global method may be used to report errors to the console or global event handlers, emulating an uncaught JavaScript exception.

```javascript
for (const fn of fns) {
  try {
    fn();
  } catch (error) {
    // add your error handling but also
    // trigger global error handlers
    reportError(error);
  }
}

// Console output:
// I'm first!
// message:Oh no!, lineno: 24
// I'm third!
```

That works perfectly and `reportError` is such a handy addition to JavaScript. And the best thing: in terms of cross-browser support, we're almost there!

![Browser support table showing all browser supporting reportError](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/do2varvwexzdpnhto6ff.png)

But keep in mind, even though `reportError` will soon be cross-browser supported, to feature detect its availability. As [Eric Bailey pointed out recently, "”Evergreen” Does Not Mean Immediately Available"](https://css-tricks.com/evergreen-does-not-mean-immediately-available/).

If you're looking for more information on `reportError` have a look at the following resources:

- [`reportError` on MDN](https://developer.mozilla.org/en-US/docs/Web/API/reportError)
- [The PR adding `reportError` to the WHATWG spec](https://github.com/whatwg/html/pull/1196)
- [An old but interesting discussion on `esdiscuss.org`](https://esdiscuss.org/topic/a-way-of-explicitly-reporting-exceptions)