Exception Handling in JavaScript: Introduction to Core Concepts - Exceptional code: introducing the basics of JavaScript exceptions
(Page 2 of 4 )
In order to understand how exceptions work in JavaScript, I’ll start with the basics –- a simple function. When a function is invoked, the only method implemented for passing data back to the calling code is the return statement. This condition is exemplified by the function listed below:
function loanCalculator(loanAmount,loanTerm){
if(loanAmount<100000){
return 'Loan Amount must be at least $100000';
}
if(loanTerm<1){
return 'Loan term must be an integer positive value';
}
return parseFloat(loanAmount)/parseInt(loanTerm);
}
The function simply acts like a Utopian loan calculator (yes, no interest is charged), which returns the value of the monthly assessment to be paid according to both the loan amount and loan term arguments. Despite its simplicity, the example shows how to send data back to the fragment of code that called the function.
The above sample function might be called like this:
// call loanCalculator
alert(loanCalculator(100000,20));
Regardless of how calling code handles the data passed back by the function, what I’ve done is verify with a couple of checking lines whether the arguments conform at least to a minimum value, in order to avoid an ugly error triggered by a zero division operation. But, the problem with this function is that it requires additional code for checking input parameters. What if I want the function to save itself from possible illegal arguments? Sure I could rewrite the function like this:
function loanCalculator(loanAmount,loanTerm){
if(!loanAmount || parseFloat(loanAmount)<1 || parseFloat(loanAmount)>300000){loanAmount=300000};
if(!loanTerm || parseInt(loanTerm)<1 || parseInt(loanTerm)>30){loanTerm=30};
return parseFloat(loanAmount) / parseInt(loanTerm);
}
And in turn, it’d be called as follows:
// call loanCalculator
alert(loanCalculator1(100000,25));
Again, I’ve coded the function for assigning default values when arguments are out of a given range. In both cases, the function is tasked with solving potential error conditions within its scope. While the examples may look like possible solutions for returning valid values, this method is considered a “bad habit” from a programming point of view.
It’s much simpler to code and read a function that does its business as long as it can, but delegates handling potential errors to a different fragment of code. This is possible by using the “throw” statement, which launches an exception within the function scope, but that can be trapped by a piece of code, at a different place inside the program. Take a look at the same function, this time using the “throw” statement:
function loanCalculator(loanAmount,loanTerm){
if(!loanAmount || parseFloat(loanAmount)<10000 || parseFloat(loanAmount)>300000){
// throw exception
throw 'Loan amount must be between $10000 and $100000';
}
if(!loanTerm || parseInt(loanTerm)<1 || parseInt(loanTerm)>30){
// throw exception
throw 'Loan term must be an integer positive value between 1 and 30';
}
return parseFloat(loanAmount) / parseInt(loanTerm);
}
As you can see, now the above function uses the “throw” statement to launch an exception when something goes wrong. What’s more interesting about the rewritten function is that the payment assessment is still returned to the calling code, while when something “exceptional” occurs, the function itself delegates error handling to specific code, generally placed outside its scope. Program control is transferred to responsible code (if any) to handle unexpected conditions.
The concept of exceptions is easily understood with the above example. The goal of exceptions is to provide a built-in mechanism, which is triggered when something unusual happens (usually runtime errors), in order to handle conflictive situations, while keeping the rest of the code focused on normal program execution.
Such a powerful mechanism complements the pillars of the object-oriented paradigm, which dictates that any object should be only accessed through its interface. So, exceptions can be considered a part of the three big features of the object’s interface, meaning that a programmer is able to get at an object by using its properties, methods, and exceptions.
Now, by returning to the simple function you just saw, “throw” statements were used to report whenever an argument was considered invalid. As I explained before, when an exception is thrown, it should be caught by a fragment of code aimed at dealing in some way with raised errors. Hence there are “try-catch” blocks in JavaScript. Therefore, let’s take a look at them and explain the role that they play in JavaScript programs.
Next: Trapping exceptions: explaining “try-catch” blocks >>
More JavaScript Articles
More By Alejandro Gervasio