{ JavaScript Errors. }

Objectives:

By the end of this chapter, you should be able to:

What is An Error

An error is a problem in your code that may or may not stop the code from running. An error in a JavaScript program occurs for one of two main reasons: either the code that is written is not valid JavaScript code, or the code is valid, but it is trying to do something that is not allowed. In the next sections we will talk about some common examples.

How Errors work in JavaScript

All errors in JavaScript are actually objects that are created by a function called Error. You can read more about it here. As MDN says, "error objects are thrown when runtime errors occur. The Error object can also be used as a base object for user-defined exceptions."

So what does this mean? A runtime error is an error that occurs when code is executed. For example, if you hop into the Chrome console and write some invalid JavaScript (e.g. var 8 = 9;), you won't actually see any errors show up until you try to run the code.

JavaScript has many built-in errors, which we'll talk about in just a moment. But you can also create and throw your own errors in applications that you write (this is what is meant by a "user-defined exception").

Common JavaScript Errors

Let's look at four common errors we encounter we writing JavaScript. You have probably seen quite a few of these before!

var x = "hello;

var wrongObj = {
    name: "foo"
    missingComma: true
};
amazing; // ReferenceError - does not exist in the global scope

function defineSomething(){
    var secret = "I'll never tell";
}

defineSomething();

secret; // ReferenceError - only exists in the scope of the defineSomething function
undefined(); // TypeError - undefined is NOT a function!

var obj = {
    name: "Elie"
};

obj.something; // this actually returns undefined! What does that tell us? If you try to access a property on an object and it does not exist, you do NOT get a ReferenceError, you just get undefined

obj.something.foo; // but when you try to access a property on `undefined`... well, that's a TypeError.

obj.something(); this is a TypeError for the same reason that undefined() is, since obj.something is undefined!
function callMe(){
    callMe();
}

callMe(); // maximum call stack size exceeded. We will talk more about the call stack and recursion in a later section.

Recursion is a more advanced concept that we won't touch on much in this course. It's good to know about this error, but if you're not writing recursive functions it's much less likely that you'll encounter it.

Catching and Throwing Errors in JavaScript

When an error is thrown, our code stops executing. Sometimes we don't know if our code is going to throw an error or not, so instead of our code crashing and not continuing to run, we might want to gracefully handle our errors. We call this "catching" our errors. To do this we use a try / catch statement. We place code inside of the try block (a block is defined as code inside of a {}) and if an error is thrown, the code moves to the catch block. After the catch block, code continues to execute.

try {
    thisDoesNotExist;
} catch(e) {
    console.log("The error is ", e);
}

On the other hand, when developing applications or libraries, we sometimes want to throw an error when something is done incorrectly in our application. To return an error and stop code execution, we use the throw keyword followed by an error obect. Optionally, we can add a message string to the error to give more details about what went wrong.

throw ReferenceError("That variable does not exist!");

Another way to specify an error is to use the throw keyword followed by a string:

throw "This will also be an error";

Let's write a small example to see what it would be like using throw, try, and catch. In this example, all we are doing is generating a random number between 0 and 1. If that number is >= 0.5, we create an error and so we move to the catch. However, our code continues to run even if an error happens.

try {
    if(Math.random() >= .5) {
        throw "Let's make an error!";   
    }
    console.log("Whew...we made it.");
    console.log("We can only get here if the random number is less than .5.");
} catch(e){
    console.log("The error is ", e);
    console.log("We can only get here if an error was thrown. (Random number is greater than .5).");
} 

console.log("Moving on.....");

finally

With our try/catch block, we saw that the code in the try block will move to the catch block if an error occurs inside of it. In our try/catch statements, we can add one more special keyword called finally. Inside of the finally block, code will execute regardless of an error being thrown.

try {
    // let's randomly try to throw an error
    if(Math.random() >= .5){
        // The following code will throw:
        // Uncaught TypeError: undefined is not a function(…)
        undefined();
    }
    console.log("Whew, we made it");
} catch(e){
   console.log("We didn't make it. The error message is", e.message);
} finally {
   console.log("No matter what we will see this statement");
}

When you're ready, move on to Debugging with the Sources Tab

Continue

Get 100+ hours of free content, tutorials, and screencasts

Send us your email, and we'll give you a confirmation code to unlock all of our materials. No spam, we promise.