最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - PhantomJS error handling - Stack Overflow

programmeradmin0浏览0评论

I'm having a hard time understanding how PhantomJS handles errors.

I have a locally installed Apache server running (xampp), and when I manually visit "http://localhost/" I get the "It Works!" page.

As a test, I wrote a small file (called forceError.js) that purposely causes an unchecked exception:

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

When I run this using:

phantomjs.exe forceError.js

First I get "status: success" and then the process just hangs. I don't see either page.onError or phantom.onError being invoked.

Is there some property or something I need to turn on to get general error handling?

I'm on Windows 7, PhantomJS version 2.0.0, and running this in my "git bash" shell.

I'm having a hard time understanding how PhantomJS handles errors.

I have a locally installed Apache server running (xampp), and when I manually visit "http://localhost/" I get the "It Works!" page.

As a test, I wrote a small file (called forceError.js) that purposely causes an unchecked exception:

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

When I run this using:

phantomjs.exe forceError.js

First I get "status: success" and then the process just hangs. I don't see either page.onError or phantom.onError being invoked.

Is there some property or something I need to turn on to get general error handling?

I'm on Windows 7, PhantomJS version 2.0.0, and running this in my "git bash" shell.

Share Improve this question edited Jul 17, 2015 at 16:57 Artjom B. 61.9k25 gold badges134 silver badges229 bronze badges asked Jul 9, 2015 at 15:33 Jonathan.BrinkJonathan.Brink 25.4k20 gold badges82 silver badges124 bronze badges 3
  • 1 Might be better as an issue on GitHub. Seems like a bug in PhantomJS 2. – Artjom B. Commented Jul 9, 2015 at 20:04
  • @ArtjomB. Good idea: github.com/lichunqiang/lichunqiang.github.io/issues/13 – Jonathan.Brink Commented Jul 11, 2015 at 2:03
  • @ArtjomB. thanks: github.com/ariya/phantomjs/issues/13403 – Jonathan.Brink Commented Jul 13, 2015 at 15:59
Add a comment  | 

3 Answers 3

Reset to default 7 +100

Tested on MacOS and experienced exactly the same behaviour, which indeed is a bit unintuitive and most likely just a bug. The weird thing is that, if you call an undefined function from the top most scope phantom.onError is invoked correctly1.

As a workaround you can just wrap body of the open callback with a try/catch. Hopefully it will do the job.

Just to clarify: page.onError is invoked if an error occurred while executing code of the requested page - not the phantom script itself. I have been relying on page.onError for a while now and it seems to work pretty stable. (Although some errors only occur in phantomjs engine, but not in regular browsers.)


1 Actually: "phantom.onError" gets printed on the console infinitely as console.error is not supported by phantomjs.

The accepted answer was very helpful, but I'll supplement it with a code sample.

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 will look similar to this screen snip:

UPDATE: This appears to be a bug specifically with page.open. I noticed that phantom.onError was catching things from callbacks, just not directly inside page.open. Here is another possible workaround. This at least allows you to have all the error handling code in one spot instead of having a bunch of try/catches. NOTE: You still need page.onError for things inside 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);
});

When actually doing things with the page, I've started using this to make sure the element I am looking for is there. Since my code is in a callback, the onError methods work fine. Code for the waitFor method is here: 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
    });
});

Your app hangs because it looks there is a loop when you call console.error within phantom.onError. Check this: Phantomjs v2, consume huge memory+cpu, after throwing exception.

发布评论

评论列表(0)

  1. 暂无评论