Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Дружественная обработка ошибок библиотекой (https://javascript.ru/forum/misc/84055-druzhestvennaya-obrabotka-oshibok-bibliotekojj.html)

Gvozd 21.05.2022 19:16

Дружественная обработка ошибок библиотекой
 
Всем привет
Есть такая нетривиальная задача

Нужно поймать ошибку, обработать и бросить ее дальше
С такой задачей справляется тривиальный код
try {
    externalCodeWithError();
} catch(e) {
    processError(e);
    throw e;
}


Но проблема такого кода, что отладчик(без галочки "Pause on uncaught exceptions") не останавливается на исходной ошибке, а только на перепроброске

А хотелось бы, чтобы останавливалось именно в месте возникновения ошибки
При этом без галочки "Pause on uncaught exceptions", потому что выставляя ее, в общем случае можно получить кучу ненужнгых остановов в пойманных исключениях от другого кода

В общем, хотелось бы получить объект ошибки, сохраняя при этом возможность удобной отладки externalCodeWithError
Решение предполагается использовать в коде библиотеки, именно поэтому не хотелось бы мешать пользователям библиотеки отлаживать их код

Кто-нибудь знает кросс-браузерный/платформенный способ обработать ошибку таким образом?

Gvozd 21.05.2022 19:16

Для Chrome удалось сделать такой нетривиальный хак
Но, похоже это именно хак, да и работает он только для текущего Chrome

function externalCodeWithError() {
    throw 123;// здесь будет остановка при включенном "Pause on exceptions" и выключенном "Pause on caught exeptions"
}
function callWithErrorHandling(func) {
    // работает на Chrome 101. Но похоже скорее на недокументированную багу devtools
    function* wrap() {
        func();
    }

    try {
        for(const tmp of wrap()) {}
    } catch(e) {
        console.log(e);
        throw e;// здесь отладчик остановится еще раз, но это не так критично. главное что был останов в месте возникновения ошибки
    }

}

callWithErrorHandling(externalCodeWithError);

Gvozd 26.05.2022 01:24

Для Firefox(работает только в нем) удалось подобрать такое решение
Тоже выглядит как хак, но уже более логичный
// library code
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
var _window = iframe.contentWindow;
var callWithErrorHandling = _window.eval(`
    (function foo(func) {
        try {
            return func();
        } catch(e) {
            throw e;// Бонус от Firefox - здесь отладчик повторно не будет останавливаться
        }
    })
`);
document.body.removeChild(iframe);

// user code
function externalCodeWithError() {
    throw 123;// здесь будет остановка при включенном "Pause on exceptions" и выключенном "Pause on caught exeptions"
}
callWithErrorHandling(externalCodeWithError);


Часовой пояс GMT +3, время: 03:53.