This is just another hopeless try to handle errors in async event handlers.
A note about this example: The example here works differently than it does if it is run directly in the browser. If ran directly in the browser none of the event listeners for errors is working ("error", "unhandledrejection").
It looks similar on Windows 10 in Chrome (Version 80.0.3987.163 (Official Build) (64-bit)) and Firefox (75.0 (64-bit)).
The only way I have found to handle this is to never make any typos. But that does not work either for me.
How is this supposed to work?
window.addEventListener("error", evt => {
console.warn("error event handler", evt);
output("error handler: " + evt.message, "yellow");
});
window.addEventListener("unhandledrejection", evt => {
console.warn("rejection event handler", evt);
output("rejection handler: " + evt.message, "green");
});
function output(txt, color) {
const div = document.createElement("p");
div.textContent = txt;
if (color) div.style.backgroundColor = color;
document.body.appendChild(div);
}
const btn = document.createElement("button");
btn.innerHTML = "The button";
btn.addEventListener("click", async evt => {
evt.stopPropagation();
output("The button was clicked");
noFunction(); // FIXME:
})
document.body.appendChild(btn);
const btn2 = document.createElement("button");
btn2.innerHTML = "With try/catch";
btn2.addEventListener("click", async evt => {
evt.stopPropagation();
try {
output("Button 2 was clicked");
noFunction2(); // FIXME:
} catch (err) {
console.warn("catch", err)
throw Error(err);
}
})
document.body.appendChild(btn2);
new Promise(function(resolve, reject) {
setTimeout(function() {
return reject('oh noes');
}, 100);
});
justAnError();
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1">
<script defer src="error-test.js"></script>
EDIT - adding output from Chrome and JS Bin (Link to JS Bin example)
Loading page
Chrome/Firefox:
error handler: Script error.
JS Bin:
error handler: Uncaught ReferenceError: justAnError is not defined
rejection handler: undefined
Clicking left button
Chrome/Firefox:
The button was clicked
JS Bin:
The button was clicked
rejection handler: undefined
asyncfunctions directly as event handlers. The event system doesn't do anything with the promise they return, which is why errors in them end up being unhandled rejections. If you want to centralize error handling for them, one option would be to have a wrapper function:addEventListener("event", handler(async evt => { /*...*/ }). Thehandlerfunction would call theasyncfunction and handle any rejections using your centralized means of doing so.handleris a function taking a promise as an argument?" No, it takes anasyncfunction as an argument, and returns a function to use as the event handler; that function handles rejections:function handler(fn) { return function(evt) { fn(evt).catch(e => { /*...handle rejection in `e`... */}); }; }