Aby ułatwić sobie debugowanie, przechwytuję wszystkie dzienniki konsoli w przeglądarce Chrome, aby użytkownicy, którzy przesyłają opinię, również przekażą wszystkie dzienniki na nasz serwer. Kiedy ktoś napotyka problem w produkcji, mogę przede wszystkim przywrócić go do pracy, abym mógł usiąść i dokładniej przeglądać wszystkie dzienniki, aby określić podstawową przyczynę problemu, który napotkał użytkownik podczas produkcji.Jak mogę przesłonić/rozszerzyć ReferenceError w JavaScript w przeglądarce Chrome?
Technika, której używam do przechwytywania dzienników, powoduje przesłonięcie pliku console.log, dzięki czemu cały tekst wpisany w pierwszym argumencie zostaje zapisany w tablicy, jednocześnie wywołując starszą funkcję, dzięki czemu nadal mogę wyświetlać dzienniki w konsoli.
Problem polega na tym, że od czasu do czasu występuje nieprzechwycony wyjątek. Nie są one uwzględniane w przesyłanych dziennikach, więc nie zawsze jest jasne, co spowodowało problem. Próbowałem więc przesłonić ReferenceError, pisząc funkcję JavaScript, która przyjmuje funkcję jako argument, a następnie zwraca nową funkcję, która zajmuje się nim, np. Przechowywanie danych w zmiennej, a następnie wywołanie funkcji starszej wersji jako ostatniego kroku:
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);
}
}
przetestować funkcję overrideException, uruchomiony po kodu na konsoli:
ReferenceError = overrideException(ReferenceError);
Następnie przetestowane zwrócony funkcję nowego ReferenceError, ręcznie wyrzuceniem ReferenceError:
throw new ReferenceError("YES!! IT WORKS! HAHAHA!");
Wynikiem na konsoli to:
ReferenceError: YES!! IT WORKS! HAHAHA!
i sprawdzanie zmienną globalną output
z funkcji overrideException pokazuje, że rzeczywiście uruchomić:
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)"
Teraz, tutaj, gdzie wszystko zaczyna spadać niezależnie. W naszym kodzie, nie będziemy wiedzieć, kiedy wystąpi przechwycony wyjątek, więc testowałem go, próbując uruchomić funkcję, która nie istnieje:
ttt();
co skutkuje:
ReferenceError: ttt is not defined
Jednak w przeciwieństwie do przypadku, w którym jawnie zgłasza się błąd, w tym przypadku funkcja nie uruchamia się, a pozostaje nam tylko starsza funkcja. Zawartość zmiennej output
jest taka sama jak w pierwszym teście.
Pytanie wydaje się następujące: W jaki sposób nadpisujemy funkcję ReferenceError używaną przez silnik JavaScript do zgłaszania błędów, tak aby była taka sama, jaką używamy, gdy wyrzucamy błąd ReferenceError?
Należy pamiętać, że mój problem jest obecnie ograniczony tylko do przeglądarki Chrome; Buduję aplikację Chrome Packaged.
Zgadnij, że nie chcesz owijać swojego kodu w 'try/catch' i przetworzyć obiekt błędu, a następnie wrzucić tam ponownie? –
@CrazyTrain - Mogę to zrobić, i prawdopodobnie to zrobię. Jest to jednak żmudne i możliwe, że coś przeoczysz. Lubię rozwiązania, które są obojętne i zawierają wszystko, ponieważ generalnie są również "Jestem zbyt zajęty" :) Moim planem jest oczywiście użycie większej ilości prób/chwytów, ale wydawało mi się to tak doskonałym rozwiązaniem, więc Zacząłem w to zaglądać. – jmort253
Mam na myśli jedno monolityczne 'try/catch', które owija cały twój kod. Ponieważ wydaje się, że celem jest nie tyle radzenie sobie z błędami w miejscu, ale raczej jakoś ich sformatowanie, a następnie zawijanie całego kodu w pojedynczym "try/catch" wydaje się trochę inne niż obecne podejście do zastępowania konstruktora. Musisz tylko mieć pewność, że ponownie rzucisz wszystkie błędy, które otrzymujesz. –