phantomJS webpage timeout

Kim Isaksen picture Kim Isaksen · May 31, 2013 · Viewed 34.3k times · Source

I have set up a script to create webshots of our app. It runs perfectly and all is fine Until I encounter an image with a broken url :

 "<img src='http://testserver.our.intranet/fetch/image/373e8fd2339696e2feeb680b765d626e' />"

I have managed to break the script after 6 seconds using the below, Before it was just looping forever.

But, is it possible to ignore the network request (AKA take the image out of DOM) and then proceed to create the thumb without the image, (or with an injected image missing image !)

var page = require('webpage').create(),
    system = require('system'),
    address, output, size;

if (system.args.length < 3 || system.args.length > 5) {
    phantom.exit(1);
} else {
    address = system.args[1];
    output  = system.args[2];
    page.viewportSize = { width: 640, height: 640 };
    page.zoomFactor = 0.75;
    page.clipRect = { top: 10, left: 0, width: 640, height: 490 };
    try{
        page.open(address, function (status) {
            if (status !== 'success') {
                console.log('Unable to load the address!');
                phantom.exit();
            } else {
                window.setTimeout(function () {
                    page.render(output);
                    phantom.exit();
                }, 200);
            }
        });    
    } finally{
        setTimeout(function() {
            console.log("Max execution time " + Math.round(6000) + " seconds exceeded");
            phantom.exit(1);
        }, 6000);
    }
}

Answer

Michael Benford picture Michael Benford · Sep 16, 2013

PhantomJS 1.9 has introduced a new setting, resourceTimeout, that controls how long a request can take before it gets cancelled. Along with that, there's a onResourceTimeout event that is triggered if/when a request times out.

Here's a code snippet illustrating all of the above:

var page = require('webpage').create();  
page.settings.resourceTimeout = 5000; // 5 seconds
page.onResourceTimeout = function(e) {
  console.log(e.errorCode);   // it'll probably be 408 
  console.log(e.errorString); // it'll probably be 'Network timeout on resource'
  console.log(e.url);         // the url whose request timed out
  phantom.exit(1);
};

page.open('http://...', function (status) {
...
}

Unfortunately those options are poorly documented right now. I had to go through GitHub discussions and the PhantomJS source code in order to find them out.