官术网_书友最值得收藏!

Setting up a global PhantomJS error handler

This recipe introduces the onError callback and demonstrates how we can use it to catch and handle errors in the PhantomJS runtime. As this onError callback is attached to the phantom object, we can use it to handle errors that are not otherwise handled by try-catch statements in our PhantomJS scripts or by onError handlers attached to webpage objects.

Getting ready

To run this recipe, we will need a script that we believe has a tendency to fail.

The script in this recipe is available in the downloadable code repository as recipe04.js under chapter02. If we run the provided example script, we must change to the root directory for the book's sample code.

How to do it…

Consider the following script:

phantom.onError = function(message, trace) {
  console.error('[PHANTOMJS ERROR] ' + message);
  trace.forEach(function(t) {
    console.error('  >> [' + t.line + '] ' +
      (t.function ? '[' + t.function + '] ' : '') +
      t.file || t.sourceURL);
  });
  phantom.exit(1);
};

function doSomeErrorProneStuff() {
  throw new Error('Gremlins fed after midnight.');
}

doSomeErrorProneStuff();

console.log('Exiting cleanly.');
phantom.exit(0);

Given the preceding script, enter the following at the command line:

phantomjs chapter02/recipe04.js

Our output should look like the following:

[PHANTOMJS ERROR] Error: Gremlins fed after midnight.
 >> [13] [doSomeErrorProneStuff] chapter02/recipe04.js
 >> [16] chapter02/recipe04.js

How it works…

Our preceding example script performs the following actions:

  1. We attach the error handler by assigning the error-handling function to phantom.onError. The onError function expects two parameters: message, which is the message on the thrown error and trace, which is an array representing the call stack leading to that unhandled error.
  2. In our onError handler, we simply write the contents of the error message to the console and then write out the stack trace as well.
  3. We enter the main part of our script, declare our error-prone function (doSomeErrorProneStuff), and immediately call that function. Note that doSomeErrorProneStuff only throws an error that is unhandled, thus dumping us into the onError handler.
  4. Lastly, we write out a message to the console and then exit with a 0 status. However, this code is effectively unreachable because of the error thrown by doSomeErrorProneStuff.

Note that once we enter the onError handler, we are not returned to our previous execution context. Depending on the specifications of our script, we will need to consider how to proceed—is it sufficient just to console out the error message and stack trace? Or do we need to reattempt an operation (for example, rerun a request with different arguments or a longer timeout, and so on)? By applying a function to phantom.onError, we create a global error handler that will catch all otherwise unhandled exceptions.

There's more…

As previously mentioned, when assigned, phantom.onError effectively creates a global error handler in the PhantomJS runtime. It is worth noting here that simply setting up a function on phantom.onError is not a substitute for safe code. Our scripts should still perform the appropriate checks (for example, for types and non-null values, and so on) and use the if or try-catch statements for flow control, wherever they make sense. However, there will be occasions where it makes sense to set up error handlers with onError; for example, when we cannot know all the places where an error might occur and we must ensure that our script exits, even if it exits with an error code.

onError parameters

As previously mentioned, the onError callback function takes two parameters: message and trace. The message parameter is simple enough—it is the error message string from the unhandled error.

The other parameter, trace, is an array of objects representing the call stack leading up to the unhandled error. The individual objects in the trace array have the following properties:

  • file: This is a relative path to the source file for the code that was being executed in that stack frame; file is mutually exclusive with the sourceURL property
  • sourceURL: This is the URL for the source file for the code that was being executed in that stack frame; sourceURL is mutually exclusive with the file property
  • line: This is an integer corresponding with the line number in the source code for the code that was being executed in that stack frame
  • function: This is the name (if any) of the function being executed in that stack frame; if the function has no name, this will be an empty string

Note

We saw the properties of the trace objects in use in the onError callback function in our example script earlier in this recipe.

See also

  • The Recording debugger messages recipe in Chapter 3, Working with webpage Objects
主站蜘蛛池模板: 伊川县| 调兵山市| 沐川县| 安丘市| 武穴市| 鹤庆县| 灵台县| 满城县| 莫力| 绥德县| 宜良县| 丽江市| 凤山县| 崇仁县| 通辽市| 清河县| 大关县| 习水县| 绥棱县| 古田县| 花莲市| 枝江市| 江山市| 丹凤县| 桦甸市| 姜堰市| 安龙县| 锡林浩特市| 宝坻区| 潍坊市| 开远市| 出国| 彰武县| 博白县| 乌拉特后旗| 乐昌市| 深泽县| 沙雅县| 宁晋县| 志丹县| 石河子市|