Обработка ошибок PhantomJS
Мне сложно понять, как PhantomJS обрабатывает ошибки.
У меня есть локально установленный сервер Apache (xampp), и когда я вручную нахожу " http://localhost/" Я получаю "Это работает"!" стр.
В качестве теста я написал небольшой файл (называемый forceError.js), который специально вызывает исключение:
var page = require('webpage').create(),
url = 'http://localhost/';
page.onError = function(msg, trace) {
console.log("page.onError");
var msgStack = ['ERROR: ' + msg];
if (trace && trace.length) {
msgStack.push('TRACE:');
trace.forEach(function(t) {
msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function +'")' : ''));
});
}
console.error(msgStack.join('\n'));
};
phantom.onError = function(msg, trace) {
console.log("phantom.onError");
var msgStack = ['PHANTOM ERROR: ' + msg];
if (trace && trace.length) {
msgStack.push('TRACE:');
trace.forEach(function(t) {
msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function +')' : ''));
});
}
console.error(msgStack.join('\n'));
phantom.exit(1);
};
page.open(url, function (status) {
console.log("status: " + status);
// an undefined function
thisShouldForceAnError();
});
Когда я запускаю это, используя:
phantomjs.exe forceError.js
Сначала я получаю "статус: успех", а затем процесс просто зависает. Я не вижу ни вызова page.onError, ни phantom.onError.
Есть ли какое-то свойство или что-то, что мне нужно для включения общей обработки ошибок?
Я нахожусь в Windows 7, PhantomJS версии 2.0.0 и запускаю это в своей оболочке git bash.
Ответы
Ответ 1
Протестировано на MacOS и испытал точно такое же поведение, которое действительно немного неинтуитивно и, скорее всего, просто ошибка. Странно то, что если вы вызываете функцию undefined из верхней области видимости phantom.onError
, вызывается правильно 1.
В качестве обходного пути вы можете просто обернуть тело обратного вызова open
с помощью try/catch
. Надеюсь, это сработает.
Просто пояснить: page.onError
вызывается, если при выполнении кода запрашиваемой страницы произошла ошибка, а не phantom script.
Я уже некоторое время полагаюсь на page.onError
и, похоже, работает довольно стабильно. (Хотя некоторые ошибки происходят только в движке phantomjs, но не в обычных браузерах.)
1 Фактически: "phantom.onError"
бесконечно печатается на консоли, поскольку console.error
не поддерживается phantomjs.
Ответ 2
Принятый ответ был очень полезен, но я пополняю его образцом кода.
page.open("https://www.google.com/", function (status) {
try {
if (status !== "success") {
console.log("Unable to access network");
} else {
//do some stuff with the DOM
}
} catch (ex) {
var fullMessage = "\nJAVASCRIPT EXCEPTION";
fullMessage += "\nMESSAGE: " + ex.toString();
for (var p in ex) {
fullMessage += "\n" + p.toUpperCase() + ": " + ex[p];
}
console.log(fullMessage);
}
});
Результат будет похож на этот экранный снип:
![Вывод]()
UPDATE:
Это, по-видимому, ошибка в page.open
. Я заметил, что phantom.onError
ловил вещи от обратных вызовов, а не непосредственно внутри page.open
. Вот еще одно возможное обходное решение. Это, по крайней мере, позволяет вам иметь код обработки ошибок в одном месте вместо того, чтобы иметь кучу try/catch. ПРИМЕЧАНИЕ. Для вещей внутри page.evaluate
вам все еще нужно page.onError
.
page.open(genericSignInPageUrl, function (status) {
setTimeout(function () { //hack for page.open not hooking into phantom.onError
if (status !== "success") {
throw new Error("Unable to access network");
}
//do some stuff
}, 0);
});
Когда я делаю что-то со страницей, я начал использовать это, чтобы убедиться, что элемент, который я ищу, есть. Поскольку мой код находится в обратном вызове, методы onError
работают нормально. Код для метода waitFor
находится здесь:
https://github.com/ariya/phantomjs/blob/master/examples/waitfor.js
page.open(genericSignInPageUrl, function () {
waitFor(function () {
return page.evaluate(function () {
return document.getElementById("idOfElementToIndicatePageLoaded");
});
}, function () {
//do some stuff with the page
});
});
Ответ 3
Ваше приложение зависает, потому что он выглядит, когда вы вызываете console.error
внутри phantom.onError
. Проверьте это: Phantomjs v2, потребляйте огромную память + процессор, после исключения исключения.