Чтобы упростить отладку, я собираю все журналы консоли в Chrome, чтобы пользователи, отправляющие запись с обратной связью, также отправляли все журналы на наш сервер. Когда кто-то сталкивается с проблемой в производстве, я могу в первую очередь вернуть их к работе, чтобы затем я мог сесть и более тщательно пройти через все журналы, чтобы определить основную причину любой проблемы, с которой пользователь столкнулся в процессе производства.
Метод, который я использую для захвата журналов, включает в себя переопределение console.log, чтобы весь текст, введенный в первый аргумент, сохранялся в массиве, одновременно вызывая устаревшую функцию, чтобы я все еще мог видеть журналы в консоли.
Проблема заключается в том, когда случается случайное исключение. Они не включены в загруженные журналы, поэтому не всегда понятно, что вызвало проблему. Поэтому я попытался переопределить ReferenceError, написав функцию JavaScript, которая принимает функцию в качестве аргумента, затем возвращает новую функцию, которая с ней работает, например, сохранение данных в переменной, а затем вызывать устаревшую функцию как последний шаг:
function overrideException(legacyFn) {
/** arguments for original fn **/
return function() {
var args = [];
args[0] = arguments[0];
// pass in as arguments to original function and store result to
// prove we overrode the ReferenceError
output = ">> " + legacyFn.apply(this, args).stack;
return legacyFn.apply(this, arguments);
}
}
Чтобы проверить функцию overrideException, я запустил следующий код на консоли:
ReferenceError = overrideException(ReferenceError);
Затем я протестировал возвращенную функцию, новый ReferenceError, вручную сбросив ReferenceError:
throw new ReferenceError("YES!! IT WORKS! HAHAHA!");
Результирующий вывод на консоли:
ReferenceError: ДА! ОНО РАБОТАЕТ! Хахаха!
И проверка глобальной переменной output
из функции overrideException показывает, что она действительно выполнялась:
output
">> ReferenceError: YES!! IT WORKS! HAHAHA!
at ReferenceError (<anonymous>)
at new <anonymous> (<anonymous>:18:35)
at <anonymous>:2:7
at Object.InjectedScript._evaluateOn (<anonymous>:562:39)
at Object.InjectedScript._evaluateAndWrap (<anonymous>:521:52)
at Object.InjectedScript.evaluate (<anonymous>:440:21)"
Теперь, когда вещи начинают разваливаться. В нашем коде мы не узнаем, когда возникает неперехваченное исключение, поэтому я протестировал его, пытаясь запустить функцию, которая не существует:
ttt();
Результат:
ReferenceError: ttt не определен
Однако, в отличие от случая, когда мы явно бросаем ошибку, в этом случае функция не запускается, и у нас остается только устаревшая функциональность. Содержимое переменной output
будет таким же, как в первом тесте.
Итак, вопрос выглядит следующим образом: Как мы переопределяем функциональность ReferenceError, которую движок JavaScript использует для выброса ошибок, так что это то же самое, что мы используем, когда мы бросаем ReferenceError?
Имейте в виду, что моя проблема ограничена только Chrome в это время; Я создаю приложение Chrome Packaged.