Professional JavaScript | 8 | WebReference

Professional JavaScript | 8

1234
[next]

Professional JavaScript

Exception Handling

When a function or method is called, the only mechanism described to date for passing information back to the script fragment that called the function of method is the return statement. What if something goes wrong? This example illustrates:


function add_like_a_child(num1, num2)
{
  if ( num1 + num2 > 20 )
    return "finger & toe limit passed!"
  if ( num1 + num2 > 10 )
    return "finger limit passed!"
  return num1 + num2; 
}

The problem with this function is that every time it gets used, additional code is required to check the return value. One never knows until after that check whether the function has failed to work usefully or not. In this case, you may have to do two checks, one for each unusual case. If the function was complex, you may have to do many checks. How tedious. Here's an example of using this function:


var result = add_like_a_child(3, 5)
if ( result == "finger & toe limit passed!")
{
  // do something to cope …
}
else if ( result == "finger limit passed!" )
{
  // do something else to cope …
}
// carry on normally if we reach this point.

In Java, this kind of difficult case is handled with exceptions. The general goal of exceptions is to provide a mechanism that reports when the extraordinary has happened. With such a mechanism in place, one can rely on return values reporting only the ordinary – normal, successful output from the function. With the extraordinary taken care of, there's no need for special, extra checks of the function's return value.

To a degree, JavaScript tries to mimic Java in its syntax. Exceptions are a proposed 'ECMAScript 2' enhancement to the language and appear in both Microsoft JScript 5.0 and JavaScript 1.4. They are likely to become a much-used feature of JavaScript in the future. The reason for this is based on the imperative that if an object is to be used in a script, the scriptwriter must have available access points where he can get at that object. These access points combined make up the object's interface, or signature. In computer language terms, the big three features of object interfaces are properties (also called attributes), methods and exceptions. Hence there are exceptions in JavaScript.

In Java you have to rigidly declare the type of thing that an exception is. True to form, in JavaScript your exception can be any old thing. Here's the official syntax for the JavaScript statements supporting exceptions. First, to create an exception:

throw expression;

Secondly, to handle an exception:


try
  statement-block
catch ( identifier )                // variant1, can be repeated
  statement block
catch ( identifier if condition )   // variant2, can be repeated
  statement block
finally                             // optional, at most one.
  statement block
Here is the example function above re-written:

function add_like_a_child(num1, num2)
{
  if ( num1 + num2 > 20 )
    throw "finger & toe limit passed!"
  if ( num1 + num2 > 10 )
    throw "finger limit passed!"
  return num1 + num2; 
}

In this function, if a throw statement is ever executed, processing of the function stops, and the function returns immediately. No ordinary return value is returned. Instead, an exception is returned.

Here is the calling code rewritten:


var result;
try {
  result=add_like_a_child(3,5);
  if ( result == 8 )
  {
    // give chocolate
  }
  else
  {
    // give Brussels sprouts
  }
}
catch (error) {
  if ( error == "finger & toe limit passed!" )
  {
 
     // do something to cope
  }
  if ( error == "finger limit passed!" )
  {
     // do something else to cope
  }
}

In this script, the result variable might never be set in the third line. If the function returns an exception, processing immediately jumps straight to the catch statement, which has access to the exception in the error variable, and the statements in the block following the catch statement are executed instead. If there is no exception, and the function returns normally, then processing continues with the next statement in the try block, and when that block is finished, the catch block is stepped over entirely, similar to an unused branch of an if statement.

The whole explanation gets a lot easier once you know a little jargon, so here you go. If something goes wrong, you say the function throws an exception. The function is called in a try block and exceptions are handled in catch blocks. The finally block is executed if no exception is outstanding at the end.

The rules for how this complicated processing all works are as follows:

If a throw statement is reached in a function (or in any block-like piece of code), then that function will not continue. It will not return a value, and it will not return void. Instead, it will cease immediately and the exception will be created. In simplistic terms, the exception appears effectively by magic.

If the statement or function causing the exception is not inside a try block, then a runtime interpreter error will occur and the script will stop. If the statement or function is called inside another function, method or block, then that collection of statements will be aborted as well and the exception passed up to the next level of control until a try block is found, or an error results, as before.

If the statement or function causing an exception is inside a try block, then any further statements in the try block are ignored. The interpreter looks through any catch blocks that might be present. If one is found with satisfactory criteria, that single catch block is executed. If any exception remains, because no catch block has satisfactory criteria, or there are no catch blocks, or a catch block raised a new exception, then the finally clause is avoided. Otherwise, all is in order and the finally clause is executed.

What are catch block criteria? There are two cases, illustrated here:


catch (stuff) { ... }
and
catch (stuff if (stuff  > "Error 1")) { ... }

In the first case, the catch block matches all exceptions. In the second case, the catch block only matches those exceptions that pass the if criteria. If there are multiple catch blocks, then the first case will catch everything, much like the default: clause of a switch statement, so it makes sense to put it last in the list of catch blocks. The stuff variable tracks the exception, and it acts within the catch block like a function parameter. The catch block treats the variable stuff in much the same way that this further script treats the variable stuff2:


function something(stuff2)
{
…
}
1234
[next]
and
Created: February 12, 2001
Revised: February 16, 2001

URL: http://webreference.com/programming/javascript/professional/chap3/