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

Как я могу захватить ошибки JavaScript, сгенерированные на странице, выбранной PhantomJS?

У меня есть PhantomJS script, который загружает локальный HTML файл, вставляет некоторые файлы javascript, а затем выполняет некоторый javascript в контексте страницы. Выполняемый javascript генерирует исключение, но я получаю только вывод из консоли, который, как представляется, не различает ошибку и обычный журнал и не имеет файлов, номеров строк или stacktrace.

То, что мне нужно, это способ зафиксировать или иным образом отличить эти ошибки. Я уже пробовал:

  • Обертка моего PhantomJS script в try-catch
    • Результат: ничто не выбрасывается достаточно далеко, чтобы быть пойманным этим
  • Определить функцию window.onerror
    • Результат: ничего не происходит. WebKit не реализует событие onerror в окне

Я бы предпочел иметь возможность получить сам объект ошибки, чтобы получить стек.

4b9b3361

Ответ 1

Я думаю, что были проблемы с window.onerror неправильно работающими в WebKit (https://bugs.webkit.org/show_bug.cgi?id=8519). Не знаю, было ли это исправлено вообще, и если да, то если версия QT WebKit уже обновлена.

Однако вы должны уловить исключения, брошенные в ваш код. Если вы используете что-то вроде webPage.evaluate(...) для запуска вашего кода, вы не можете завершить полный вызов в блоке try/catch, так как script оценивается в другом контексте, и ошибки не будут отображаться в главном контексте выполнения. Вместо этого вам придется поймать ошибки в контексте выполнения страницы. К сожалению, нет способа доступа к каким-либо функциям, определенным в основном контексте, поэтому мы должны явно написать код обертки вокруг вашего кода, который будет выполнен.

Ниже приведен модифицированный пример файла phantomwebintro.js, который включен в источник PhantomJS. Он загружает HTML-страницу, вставляет script, а затем запускает некоторый код в контексте страницы (здесь с линией, бросающей ошибку типа). Этот код обернут блоком try/catch и вернет завершенный результат или объект ошибки в основной контекст.

...

// Load an HTML page:
page.open("http://www.phantomjs.org", function(status) {
    if (status == "success") {

        // Inject some scripts:
        page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {

            // Run your own code in the loaded page context:
            var resultWrapper = page.evaluate(function() {
                var wrapper = {};
                try {
                    // Your code goes here
                    // ...

                    var x = undefined.x; // force an error

                    // store your return values in the wrapper
                    wrapper.result = 42;
                } catch(error) {
                    wrapper.error = error;
                }
                return wrapper;
            });

            // Handle the result and possible errors:
            if (resultWrapper.error) {
                var error = resultWrapper.error;
                console.log("An error occurred: " + error.message);
                // continue handling the error
                // ...
            } else {
                var result = resultWrapper.result;
                // continue using the returned result
                // ...
            }

            ...

        });
    }
});

...

Ответ 2

Решение? return true!

      // Error tracking
      page.onError = function(msg, trace) {
          console.log('= onError()');
          var msgStack = ['  ERROR: ' + msg];
          if (trace) {
            msgStack.push('  TRACE:');
            trace.forEach(function(t) {
              msgStack.push('    -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function + '")' : ''));
            }); 
          }   
          console.log(msgStack.join('\n'));

          // Consider error fully handled
          return true;
      };