RangeError, TypeError, and URIError JavaScript Error Types

By Rob Gravelle

The RangeError, TypeError, and URIError JavaScript Error Types

JavaScript divides runtime errors into six separate error types. The benefit to us as developers is that we can more accurately pinpoint exactly what kind of error we're dealing with. In the Handling JavaScript Errors by Type article, we learned how to distinguish between different error types using the Error.name property as well as the SyntaxError, EvalError, and ReferenceError error types. Today, we'll be covering the RangeError, TypeError, and URIError types. We'll also see how to create our own error type.

The RangeError

A RangeError is thrown under a couple of circumstances. The first happens when you pass a number as an argument to a function that lies outside the range of permissible values. For instance, when creating an array with an illegal length, or when passing invalid values to the numeric methods Number.toExponential(), Number.toFixed(), or Number.toPrecision(). For the record, an array in JavaScript can have 0 to (2^32-1) elements, or 4,294,967,295. Both Number.toExponential() and Number.toFixed() accept arguments from 0 to 20, while Number.toPrecision()'s expected range is from 1 to 21 inclusive.

var a = new Array(4294967295);  //OK
var b = new Array(-1); //range error

var num = 2.555555;
document.writeln(num.toExponential(4));  //OK document.writeln(num.toExponential(-2)); //range error!

num = 2.9999;
document.writeln(num.toFixed(2));   //OK
document.writeln(num.toFixed(25));  //range error!

num = 2.3456;
document.writeln(num.toPrecision(1));   //OK
document.writeln(num.toPrecision(22));  //range error!

Another, albeit lesser known cause of RangeErrors are recursive functions like the one below that end up exhausting all the available stack space. While each browser displays its own error message, Safari does clearly identify it as a RangeError:

var a = new Array(1);
function recurse(a){
    a[0] = new Array(1);
    recurse(a[0]);
}

recurse(a); //displays "RangeError: Maximum call stack size exceeded."

The TypeError

Although JavaScript does employ something called loose typing, it certainly does recognize all of the usual data types, such as numbers, strings, objects, arrays, and the JavaScript-specific "function" type. Use the wrong type for a given operation, and a TypeError will result:

 var num = 234; num.substr(1,1); //uncaught exception: TypeError: num.substr is not a function

var p1 = document.createElement('p');
//the event handler is an inline function so the boolean value of true //is being passed to the addEventListener() method p1.addEventListener("click", function() { return true; }(), false); //Object doesn't support this property or method 

The URIError

A URIError is thrown by the decodeURI(), decodeURIComponent(), encodeURI(), encodeURIComponent(), escape(), and unescape() URI handling functions when they are passed a malformed URI. Here's an example that generates a URIError while attempting to decode the string "%". This happens because the "%" character represents the beginning of a URI escape sequence. Since nothing follows the "%", the string is an invalid escape sequence:

decodeURIComponent("%");
//The URI to be decoded is not a valid encoding 

Other special URI characters include:

  • Colon (:)
  • Forward Slash (/)
  • Semi-colon (;)
  • Question-mark (?)
  • Hash (#)

Throwing Your Own Errors

For handling errors in your own code, it's common practice to subclass the generic error types and create your own. To that end, here's some code that defines, throws, and handles a custom child of the RangeError object:

 function MyRangeError(message) { 
  this.name    = 'MyRangeError'; 
  this.message = message || 'A MyRangeError ocurred!';
}  
// Inherit from the RangeError's prototype.
MyRangeError.prototype = new RangeError(); 
MyRangeError.prototype.constructor = MyRangeError;  

function setTop50ListItem(index, item) {
  if (index < 1 || index > 50) {
    throw new MyRangeError('The index has to be between 1 and 50.');
  }
  else {
    //array is zero based
    top50List[index - 1] = item;
  }
}

var top50List = new Array(50);
try {
  setTop50ListItem(51, 'Rob Gravelle');
} catch (e) {
  if (e.name == 'MyRangeError') {
    alert('My Error: ' + e.name + ' Message: ' + e.message);
  }
  else {
    alert(e.name + ' Message: ' + e.message);
  }
}

Conclusion

Including Error Handling in your scripts is not only the right thing to do, but if you really want to do it right, your visitors/users and developers would be well served by including more precise error trapping. The Java standard is to subclass generic error types in your own methods. There are no drawbacks to doing the same in JavaScript.


If you enjoyed this article, please contribute to Rob's less lucrative music career by purchasing one of Rob's cover or original songs from iTunes.com for only 0.99 cents each.

Rob Gravelle resides in Ottawa, Canada, and is the founder of GravelleConsulting.com. Rob has built systems for Intelligence-related organizations such as Canada Border Services, CSIS as well as for numerous commercial businesses. Email Rob to receive a free estimate on your software project. Should you hire Rob and his firm, you'll receive 15% off for mentioning that you heard about it here!

In his spare time, Rob has become an accomplished guitar player, and has released several CDs. His former band, Ivory Knight, was rated as one Canada's top hard rock and metal groups by Brave Words magazine (issue #92).

Rob uses and recommends MochaHost, which provides Web Hosting at $3.10 per month, 2 LifeTime Free Domains, and 6 Months Free!



Make a Comment

Loading Comments...

  • Web Development Newsletter Signup

    Invalid email
    You have successfuly registered to our newsletter.
  •  
  •  
  •  
Thanks for your registration, follow us on our social networks to keep up-to-date