Reputation: 497
I just started working with CasperJs, and I'm having difficulty debugging it because so many coding mistakes seem to cause the script to exit without providing an error message. When you use verbose mode, you get the messages you should get up until the offending line of code, and at that point it just quits.
For example, if I execute the code:
var casper = require('casper').create({
verbose: true,
logLevel: "debug"
});
casper.start('https://www.google.com/#q=stackoverflow', function(){
});
casper.wait(2000, function(){
});
casper.then(function() {
hrefAr = this.evaluate(getLinks);
this.log(hrefAr.length + ' links found', 'info');
this.exit();
});
casper.run(function() {
this.exit();
});
function getLinks() {
var links = document.querySelectorAll('a');
return Array.prototype.map.call(links, function(e) {
return e.getAttribute('href');
});
}
I get the following results:
...a bunch of info & debug messages, followed by...
[info] [phantom] Step 4/4 https://www.google.com/search?q=stackoverflow&cad=h (HTTP 200)
[info] [phantom] 89 links found
[debug] [phantom] Navigation requested: url=about:blank, type=Other, lock=true, isMainFrame=true
[debug] [phantom] url changed to "about:blank"
If I add a log statement to the function getLinks...
...code as shown above...
function getLinks() {
this.log('getLinks ran', 'info');
var links = document.querySelectorAll('a');
...code as shown above...
...this causes to script to fail, like so:
...the same info & debug messages...
[info] [phantom] Step 4/4 https://www.google.com/search?q=stackoverflow&cad=h (HTTP 200)
...NO LOGS, ECHOS, OR RESULTS PAST THIS POINT, JUST THESE TWO CLOSING STATEMENTS...
[debug] [phantom] Navigation requested: url=about:blank, type=Other, lock=true, isMainFrame=true
[debug] [phantom] url changed to "about:blank"
It doesn't tell you that anything has gone wrong, it just sends you back to blank and ends execution.
Is there a way to get better error reporting? Or any error reporting?
When I try to implement the workaround below using the following code:
var casper = require('casper').create({
verbose: true,
logLevel: "debug"
});
casper.start('https://www.google.com/#q=stackoverflow', function(){
});
casper.wait(2000, function(){
});
casper.then(function() {
reportErrors(function() {
hrefAr = this.evaluate(getLinks);
this.log(hrefAr.length + ' links found', 'info');
this.exit();
});
});
casper.run(function() {
this.exit();
});
function getLinks() {
//this.log('getLinks ran', 'info');
var links = document.querySelectorAll('a');
return Array.prototype.map.call(links, function(e) {
return e.getAttribute('href');
});
}
function reportErrors(f) {
var ret = null;
try {
ret = f();
} catch (e) {
casper.echo("ERROR: " + e);
casper.exit();
}
return ret;
}
I get...
...info & debug messages shown above...
[info] [phantom] Step 4/4 https://www.google.com/search?q=stackoverflow&cad=h (HTTP 200)
ERROR: TypeError: undefined is not a constructor (evaluating 'this.evaluate(getLinks)')
--THIS IS WHERE MY LINK COUNT WOULD BE REPORTED
[debug] [phantom] Navigation requested: url=about:blank, type=Other, lock=true, isMainFrame=true
[debug] [phantom] url changed to "about:blank"
Upvotes: 1
Views: 1828
Reputation: 61892
Until the error swallowing in PhantomJS 2.x is fixed, you can try several things:
Use PhantomJS 1.9.8. The underlying QtWebKit engine is more than 5 years old by now, but it still works rather well most of the time. You can add commandline options such as --ignore-ssl-errors=true
if there are SSL/TLS problems. CasperJS supports changing the PhantomJS version on demand for the current terminal session by setting the PHANTOMJS_EXECUTABLE
environment variable to the executable or path of executable that you want to use. For example, on Windows: set PHANTOMJS_EXECUTABLE=phantomjs198
(I have them numbered and in the PATH).
If it's the syntax errors, you're worried about, then run a linter over your code first. I can recommend eslint and jshint.
Use additional events to detect errors (with PhantomJS 1.9.8): resource.error
, page.error
, remote.message
and casper.page.onResourceTimeout
. Example
Regarding your special function. this
has not meaning in the callback of reportErrors
. You need to bind another object:
casper.reportErrors = function (f) {
var ret = null;
try {
ret = f.call(this);
} catch (e) {
this.echo("ERROR: " + e);
this.exit();
}
return ret;
}
and then you can use it as before:
casper.then(function() {
this.reportErrors(function() {
hrefAr = this.evaluate(getLinks);
this.log(hrefAr.length + ' links found', 'info');
this.exit();
});
});
Upvotes: 2
Reputation: 3859
There is an open PhantomJS issue on this.
You can get around it by wrapping each then
& similar with a reportErrors
function, e.g.:
function reportErrors(f) {
var ret = null;
try {
ret = f();
} catch (e) {
casper.echo("ERROR: " + e);
casper.exit();
}
return ret;
}
casper.then(function() {
reportErrors(function() {
...
});
});
Upvotes: 3