2015-07-09 2 views
10

Мне сложно понять, как 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

Может быть лучше, как проблема на GitHub. Похоже на ошибку в PhantomJS 2. –

+0

@ArtjomB. Хорошая идея: https://github.com/lichunqiang/lichunqiang.github.io/issues/13 –

+0

@ArtjomB. Спасибо: https://github.com/ariya/phantomjs/issues/13403 –

ответ

7

Протестировано на MacOS и испытал точно такое же поведение, что действительно немного неинтуитивно и, скорее всего, просто ошибка. Странно то, что если вы вызываете , то неопределенная функция из верхней части области видимости phantom.onError правильно вызывается .

В качестве обходного пути вы можете просто обернуть тело обратного вызова open с помощью try/catch. Надеюсь, это сработает.

Просто чтобы уточнить: page.onError вызывается, если при выполнении кода запрашиваемой страницы произошла ошибка, а не собственно фантомный скрипт. На данный момент я полагаюсь на page.onError и, похоже, работает довольно стабильно. (Хотя некоторые ошибки возникают только в phantomjs двигателя, но не в регулярных браузерах.)


На самом деле: "phantom.onError" печатается на консоли, как бесконечно console.error не поддерживается phantomjs.

+0

Попробуйте 'return true;' на 'page.onError' –

6

Принятый ответ был очень полезным, но я дополню его образцом кода.

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); 
    } 
}); 

Вывод будет выглядеть на этот экран надреза: Output

UPDATE: Это, кажется, ошибка именно с page.open. Я заметил, что phantom.onError ловил вещи от обратных вызовов, только не прямо внутри page.open. Вот еще одно возможное обходное решение. Это, по крайней мере, позволяет вам иметь код обработки ошибок в одном месте вместо того, чтобы иметь кучу try/catch. ПРИМЕЧАНИЕ. Вам все еще нужно page.onError для вещей внутри page.evaluate.

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 
    }); 
}); 
Смежные вопросы