Вывести ошибку из слушателя

Описание

В проекте есть некая конструкция 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 шт):

Автор решения: Andrei

По моему ловит если правильно использовать:

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>

→ Ссылка
Автор решения: EzioMercer

Это не возможно, т.к. слушатели - это асинхронные функции. Асинхронные функции возвращают промисы, а это не ошибка, даже если возвращается 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)

→ Ссылка