Pytanie Obsługa błędów PhantomJS


Ciężko mi zrozumieć, w jaki sposób PhantomJS radzi sobie z błędami.

Mam zainstalowany lokalnie serwer Apache (xampp) i kiedy ręcznie odwiedzam "http: // localhost /"Dostaję stronę" To działa! ".

Jako test napisałem mały plik (o nazwie forceError.js), który celowo powoduje niesprawdzony wyjątek:

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

Kiedy uruchomię to za pomocą:

phantomjs.exe forceError.js

Najpierw otrzymuję "status: sukces", a proces się po prostu zawiesza. Nie widzę wywołania metody page.onError lub phantom.onError.

Czy jest jakaś właściwość lub coś, co muszę włączyć, aby uzyskać ogólną obsługę błędów?

Jestem na Windows 7, PhantomJS wersja 2.0.0, i uruchamiam to w mojej powłoce "git bash".


10
2017-07-09 15:33


pochodzenie


Może być lepszy jako problem na GitHub. Wygląda jak błąd w PhantomJS 2. - Artjom B.
@ArtjomB. Dobry pomysł: github.com/lichunqiang/lichunqiang.github.io/issues/13 - Jonathan.Brink
@ArtjomB. dzięki: github.com/ariya/phantomjs/issues/13403 - Jonathan.Brink


Odpowiedzi:


Przetestowano na MacOS i doświadczyłem dokładnie tego samego zachowania, które w istocie jest nieco nieintuicyjne i najprawdopodobniej tylko błędem. Dziwne jest to, że jeśli zadzwonisz niezdefiniowana funkcja od najwyższego zakresu phantom.onError jest wywoływany poprawnie1.

Aby obejść ten problem, można po prostu owinąć ciało open wywołanie zwrotne za pomocą try/catch. Mam nadzieję, że to się uda.

Aby wyjaśnic: page.onError jest wywoływany, jeśli wystąpił błąd podczas wykonywania kodu żądanej strony - nie sam skrypt fantomowy. Na czym polegam page.onError od jakiegoś czasu i wydaje się działać dość stabilnie. (Chociaż niektóre błędy występują tylko w silniku phantomjs, ale nie w regularny przeglądarki).


1 Tak właściwie: "phantom.onError" zostanie wydrukowany na konsoli w nieskończoność jako console.error nie jest obsługiwany przez phantomjs.


7
2017-07-17 20:10



Próbować return true; na page.onError - Alexis Canyon


Przyjęta odpowiedź była bardzo pomocna, ale uzupełnię ją o próbkę kodu.

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

Dane wyjściowe będą wyglądać podobnie do tego wycinku ekranu: Output

AKTUALIZACJA: Wygląda na to, że jest to błąd specyficzny dla page.open. zauważyłem to phantom.onError było łapanie rzeczy od callbacków, po prostu nie bezpośrednio w środku page.open. Oto inne możliwe obejście. To przynajmniej pozwala ci mieć cały kod obsługi błędów w jednym miejscu, zamiast mieć kilka prób / chwytów. UWAGA: Nadal potrzebujesz page.onError do rzeczy w środku 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);
});

Kiedy faktycznie robię rzeczy ze stroną, zacząłem używać tego, aby upewnić się, że element, którego szukam, istnieje. Ponieważ mój kod jest w wywołaniu zwrotnym, onError metody działają dobrze. Kod dla waitFor Metoda jest tutaj: 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
    });
});

6
2017-07-27 11:58





Twoja aplikacja zawiesza się, ponieważ wygląda na to, że podczas połączenia jest pętla console.error w ciągu phantom.onError. Sprawdź to: Phantomjs v2, zużywają ogromną pamięć + procesor po rzuceniu wyjątku.


1
2017-08-15 20:31