Вывести ошибку из слушателя
Описание
В проекте есть некая конструкция try { } catch. Проблема в том, что, если ошибка возникает внутри слушателя, то try его не ловит. Пример
try {
document.querySelector(`button#a`).addEventListener(`click`, (event) => {
const a = 5;
a = 8;
});
} catch (error) {
document.write(`Ошибка '${error}' была поймана!`);
}
<button id="a">Click to call error</button>
При чем, это не касается обычных функций, даже анонимных.
try {
(() => {
const a = 5;
a = 8;
})();
} catch (error) {
document.write(`Ошибка '${error}' была поймана!`);
}
Вопрос
Почему ошибки в слушателей ускользают от try?
Как такие ошибки тоже поймать при помощи try?
Ответы (2 шт):
По моему ловит если правильно использовать:
document.querySelector(`button#a`).addEventListener(`click`, (event) => {
try {
const a = 5;
a = 8;
} catch (error) {
document.write(`Ошибка '${error}' была поймана!`);
}
});
// Пример для более точного понимания
function foo() {
// Ошибка произойдет
// здесь поэтому и ловить ее нужно здесь.
try {
const a = 5;
a = 8;
} catch (error) {
document.write(`Караул ошибка '${error}' хотя она была поймана!`);
}
}
document.querySelector(`button#a1`).addEventListener(`click`, foo);
<div><button id="a">Click to call error</button></div>
<div><button id="a1">Click to call error</button></div>
Это не возможно, т.к. слушатели - это асинхронные функции. Асинхронные функции возвращают промисы, а это не ошибка, даже если возвращается Promise.reject
Даже если взять ваш же пример с анонимной функцией и сделать его аснхронным, то ошибки не будет
try {
(async () => {
const a = 5;
a = 8;
})();
} catch (error) {
document.write(`Ошибка '${error}' была поймана!`);
}
Если эта была бы обычная функция, то я могу показать как поймать ошибку извне, но я не знаю как await-тить слушатели :)
Можно например ловить ошибку в асинхронной функции:
async function asyncError() {
throw new Error("Error from asyncError()");
}
async function catchError() {
try {
await asyncError();
} catch (e) {
console.error(e);
}
}
catchError();
Или например использовать синтаксис then..catch:
async function asyncError() {
throw new Error("Error from asyncError()");
}
asyncError()
.catch(console.error)