Подтвердить что ты не робот

Как поймать исключения, вызванные обратными вызовами, переданными jQuery?

Я бы хотел поймать исключения, вызванные обратными вызовами, переданными jQuery (либо обработчикам событий, например click, либо методам jqXHR, таким как then или always).

Я определил два варианта:

  • window.onerror handler - это лишь частичное решение, потому что оно не поддерживается на Android, которое является одной из моих целевых платформ.
  • обработка исключений в каждом отдельном обратном вызове - не DRY вообще!

Единственное, что я могу придумать, это переопределить методы jQuery, но это может привести к проблемам при каждом обновлении jQuery. Для обработчиков AJAX я мог бы использовать $.ajaxSetup(за ответ на Исключения, вызванные в jQuery AJAX обратные вызовы, проглатываемые?), но я не уверен, что это позволит мне поймать все.

Есть ли другие варианты?

4b9b3361

Ответ 1

Вы можете обернуть каждый обратный вызов следующим образом:

function cbWrapper(fn) {
    return function() {
        try {
            return(fn.apply(this, arguments));
        } catch(e) {
            // handle all your exceptions here
        }
    };
}

Итак, когда вы проходите обратный вызов к вызову Ajax, вместо передачи фактического обратного вызова вы передаете cbWrapper(callback).

$.get(url, cbWrapper(myRealCallback));

Или встроенная анонимная версия будет выглядеть так:

$.get(url, cbWrapper(function() {
    // actual callback code here
}));

Более продвинутый способ сделать это - переопределить $.get() своей собственной реализацией, которая автоматически завершает обратный вызов, но это становится сложно, поскольку jQuery настолько гибко относится к тем, какие аргументы фактически переданы. Из-за этого и потому, что вам нужно переопределить один конкретный аргумент, чтобы выполнить эту работу, вам придется дублировать все их коды обнаружения аргументов, которые определяют, какие аргументы присутствуют и которые соответствуют тем фактическим параметрам функции. Этот код немного беспорядочен. Это выполнимо и, вероятно, не сломается, потому что если jQuery сломает его, тогда существующий код jQuery сломается, но он не очень чистый.

Если это все ваш собственный код, вы можете просто сделать свою собственную версию $.get(), которая не настолько гибка с позициями аргументов и переключит весь ваш код, чтобы использовать его вместо фактического $.get():

jQuery.fn.myGet = function(url, fn) {
    return(jQuery.get(url, cbWrapper(fn)));
}