Internet Explorer 5.0 Review, Part IV: Exception Handling, Programmer-checked Errors - www.docjavascript.com
Internet Explorer 5.0 Review, Part IV: Exception Handling (3)
Handling Programmer-thrown Exceptions
Exceptions are not thrown only by JavaScript. They can also be thrown intentionally and consciously by the programmer. In fact, good software engineering practices include extensive usage of exceptions as a way to simplify the code. The reason being that your normal-processing flow is then separated from the error checking parts, making your code much more readable and easier to maintain and modify. Every time you want to handle a specific error, you throw an exception. You don't have to use any if...else
to steer your flow between the normal flow and the exception-handling one. Once an exception is thrown, the flow control switches to the next catch block and all negotiations and error handling is done there. Since the programmer knows exactly which exception he or she throws, the programmer can devise such a mechanism for easily figuring out what was the exception and give a useful message to the user.
Here is a simple example that illustrates most of the exception-handling mechanisms you can use:
<HTML>
<HEAD>
<TITLE> example 1 </TITLE>
</HEAD>
<BODY>
<SCRIPT LANGUAGE="JavaScript1.2">
<!--
function createException(msgNum, msgText) {
this.messageNumber = msgNum;
this.messageText = msgText;
}
function triggerException() {
exceptionObj = new createException(1, "error blablabla");
throw exceptionObj;
}
function raiseException() {
try {
triggerException();
}
catch (exceptionObj) {
if (exceptionObj instanceof createException) {
alert("Call the programmer ASAP")
}
else {
throw exceptionObj;
}
}
}
raiseException();
// -->
</SCRIPT>
</BODY>
</HTML>
The main program is a one-line script, raiseException()
. As indicated by the function name, the only purpose of this program is to raise an exception. The body of the raiseException()
function includes the try...catch
statement:
function raiseException() {
try {
triggerException();
}
catch (exceptionObj) {
if (exceptionObj instanceof createException) {
alert("Call the programmer ASAP")
}
else {
throw exceptionObj;
}
}
}
The try block creates an exception object and throws it:
function triggerException() {
exceptionObj = new createException(1, "error blablabla");
throw exceptionObj;
}
The exception object is a regular JavaScript object. In this case we named our object exceptionObj
, but it could have been named kuku
just as well. The purpose of the exception object is to carry data from the try block to the catch block, for deciphering it and reporting the error's details to the user. The exception object may include as many properties and methods as you like. In our case, we define two properties: the message number of the error and its textual message. The object creation function is regular JavaScript:
function createException(msgNum, msgText) {
this.messageNumber = msgNum;
this.messageText = msgText;
}
The catch block has a single parameter that can be of any data type. An object passed to the catch block communicates the error number and the error message. Notice the object type verification we do first:
if (exceptionObj instanceof createException)
This check is necessary in order to distinguish between JavaScript and programmer-checked errors. The catch block, as its name indicates, catches all exceptions thrown in the relevant try block. For the user to get the correct error message, we need to decide if the exception was thrown by JavaScript (accessing out-of-range array element, for example) or by the programmer. The best way to do it is to verify that the exception object is of the same type we create these objects with. If the type matches, we are sure the exception is for us to handle. In our example, we just display a message to the user:
if (exceptionObj instanceof createException) {
alert("Call the programmer ASAP")
}
If the type does not match, we keep throwing the exception upward. Exception handling is nested. You can place a try...catch
statement within another try block, so every time you have an exception thrown from the first catch
block, it is caught by the parent catch block. In our case, there is no a higher-level try...catch
statement, so the exception is handled by the operating system. The operating system handles all exceptions that were not handled before by lower-level catch blocks. Here is the exception throwing in our example:
else {
throw exceptionObj;
}
Let's enhance the script a bit. In the script above, we specify the message's number and description when creating the exception object:
exceptionObj = new createException(1, "error blablabla");
But then the triggerException()
and raiseException()
functions are suitable for only one exception type. To make them generic, we added the error's number and text parameters to the two functions above:
<HTML>
<HEAD>
<TITLE> example 1 </TITLE>
</HEAD>
<BODY>
<SCRIPT LANGUAGE="JavaScript1.2">
<!--
function createException(msgNum, msgText) {
this.messageNumber = msgNum;
this.messageText = msgText;
}
function triggerException(messageNum, messageTxt) {
exceptionObj = new createException(messageNum, messageTxt);
throw exceptionObj;
}
function raiseException(num, message) {
try {
triggerException(num, message);
}
catch (exceptionObj) {
if (exceptionObj instanceof createException) {
alert("Call the programmer ASAP")
}
else {
throw exceptionObj;
}
}
}
raiseException(1, "Doc JavaScript Column 36");
// -->
</SCRIPT>
</BODY>
</HTML>
Produced by Yehuda Shiran and Tomer Shiran
Created: April 26, 1999
Revised: April 26, 1999
URL: https://www.webreference.com/js/column38/usererror.html