Paul Tarjan Paul Tarjan - 18 days ago 6
Javascript Question

How to deal with dangling promises

Oftentimes I want to call a promise and just let it run asynchronously instead of waiting for it. Like:

... some code ...

fetchMyCount().then(count => {
updateTheUI(count);
});

... more code ...


Now this works great, but oftentimes I don't put a failure handler on the promise because that is pretty onerous for each one. That would be like putting a
try {} catch {}
on every one of my data fetches.

The problem is, if it fails, it does so silently. It doesn't throw an exception that my
window.onerror
can get, it doesn't log, it doesn't do anything.

Now I can make a nice wrapper like:

Async(fetchMycount().then(count => {
updateTheUI(count);
}));


which can generically deal with promises, but then I have to remember to wrap each and every async call.

Is there a way to have a top-level handler like
window.onerror
or a big
try {} catch {}
wrapper that can catch all un-dealt-with rejected promises so I can log them and make sure they get fixed?

Answer

This is a common use case. Your problem is real. In Node, you have process.on("unhandledRejection", ... events which you can use. Sadly, these are not available in browsers yet. Some libraries which are compatible with ES2015 promises offer them and you can use those until native promises get support.

The upside is that support in browsers is coming and browsers will eventually support these hooks.

Currently, I've convinced the polyfill to add it, so if you're using the core-js polyfill you can do:

window.onunhandledrejection = function(e){
    // handle here e.promise e.reason
};

Note that this assumes that something is an unhandled rejection if: It's unhandled, and an error handler was not attached synchronously (within a task to be precise).