Решение: Не вызывается слушатель на событие unhandledrejection?

Олег Кусов18.05.2022
Браузеры
webpack
CORS

В процессе работы я столкнулся с довольно забавным кейсом. В приложении обработка ошибок происходила на глобальном уровне через window.addEventListener('error', () => {...}) и window.addEventListener('unhandledrejection', () => {...}) для отлова ошибок асинхронного кода.

Проблема заключалась в том, что в Firefox ошибки на проде ловились, а в Chrome нет. Дело в том, что у Chrome есть ограничения на использование слушателей для отлова ошибок - они срабатывают только при включении для подключаемых скриптов CORS. Если у вас такая же проблема и ассеты проекта подключаются с другого домена (например, лежат на S3), то вы по адресу.

Для решения необходимо скриптам прописать атрибут crossorigin='anonymous' для активации безопасного соединения без передачи кредов.

Как добавить скриптам crossorigin=anonymous через Webpack?

Для этого устанавливаем HtmlWebpackPlugin, в конфиге плагина отключаем автоматическое добавление ассетов в html темплейт через свойство inject:

{
  plugins: [new HtmlWebpackPlugin({inject: false})]
}

Теперь, чтобы добавить вручную скрипты в темплейт, вставляем следующее:

<% for(var i=0; i < htmlWebpackPlugin.files.js.length; i++) {%>
    <script type="text/javascript" src="<%= htmlWebpackPlugin.files.js[i] %>" crossorigin='anonymous'></script>
<% } %>

Не забываем про файлы стилей

<% for(var i=0; i < htmlWebpackPlugin.files.css.length; i++) {%>
    <link type="text/css" rel="stylesheet" href="<%= htmlWebpackPlugin.files.css[i] %>">
<% } %>

Также для добавления crossorigin атрибута динамически подгружаемым чанкам, добавляем в конфиг вебпака следующее:

{target: 'web', output: {crossOriginLoading: 'anonymous'}}

Проблема решена! Подписывайтесь на меня в Twitter