Errors, Exceptions, and Debugging

Errors, Exceptions, and Debugging

No matter how carefully and slowly you code, if the program is large and complex enough, errors and bugs will arise. You need to be equipped with the skills to be able to handle those situations. Being able to handle errors and how to debug properly is very important so that you can improve your code and make it safer.

Errors

An error, or exception is a way for JavaScript to let you know that something has gone wrong. When an error occurs, it is also said to be thrown.

You might have come across them on your own by accident, but here's a simple example of an error.

	
    console.log(x);
	
An example of a reference error.
An example of a reference error.

So what now?

Catching Exceptions

Catching an exception that was thrown is a way for you handle what to do when it occurs.

To catch an exception, you need to wrap the code that you think is prone to exceptions with a try-catch block.

The code inside the try is the code you want to try executing sucessfully and the code inside the catch block is the code that you want to run if an exception is thrown.

	
    try {
        console.log(x);
    } catch (error) {
        console.log(error.message);
    }
	
Catching an exception.
Catching an exception.

Recall that before the try-catch block, the exception would just be thrown. Now that we caught it thanks to the try-catch block, we can now do whatever we want with it (but in this case, we just logged the message provided by the error).

Debugging

Debugging is an inevitable part of programming and it is the act of both finding and fixing bugs.

There are many different ways in which you can debug your JavaScript code, and we'll go over two popular methods.

Logging Variables

A very basic method of debugging code is to simply add print statements.

Let's say you quickly wrote a function that returns true if a number is single digit (excluding decimals) and false if not.

	
    function isSingleDigit(number) {
        return number <= 10;
    }
    var number = (3 * 3) + 1;
    var result = isSingleDigit(number);
    console.log(result);
	
	
    true
	

You realized there was a bug in this code because the number 10 should have resulted in false but it instead resulted in true.

Well, an easy way to debug this to confirm what number is being passed into isSingleDigit to see if it returns what you expect.

	
    function isSingleDigit(number) {
        return number <= 10;
    }
    var number = (3 * 3) + 1;
    console.log(number);
    var result = isSingleDigit(number);
    console.log(result);
	
	
    true
    10
	

Because now you saw that 10 was printed, you can confirm that giving isSingleDigit the value of 10 results in an incorrect result.

Thus, you can now dive into the function and resolve the issue, which is the use of <= when it should read <.

Breakpoints

Every modern browser today comes with a JavaScript debugger that lets you more easily debug your code.

A very useful feature of these debuggers is being able to set breakpoints in your code. Breakpoints pause the executing of your code so that you can see the current values of the variables.

From there you can determine whether or not they seem normal, if so, you can continue on with the program, if not, then you know the problem is occurring earlier.

Suppose you created a simple calculator that only supports division, and it is being fed random positive integer values.

	
    function getPositiveInteger() {
        return Math.floor(Math.random() * 5)
    }
    var dividend = getPositiveInteger();
    var divisor = getPositiveInteger();
    var quotient = dividend / divisor;
    console.log(dividend + " / " + divisor + " = " + quotient);
	

The getPositiveInteger function returns a positive integer from 1 to 5, or does it? 🤔🤔🤔

The first couple of times when you run this, everything looks good. You get output like this:

	
    2 / 4 = 0.5
    3 / 2 = 1.5
    1 / 4 = 0.25
    3 / 1 = 3
	

Everything still looks good, but out of nowhere, you get this:

	
    2 / 0 = Infinity
	

Clearly something went wrong, and so it's time to debug using breakpoints!

Open your Developer Tools and go to the Sources tag. Locate the file you want to debug, and click on the line number on the left corresponding to where you want to inspect the values of the variables.

Setting a breakpoint.
Setting a breakpoint.

In our case, line 13 works great because it's the line we are doing the dividing. When you see that blue symbol appear (on Chrome), the breakpoint has been set.

Refresh the page and watch what happens.

Paused in debugger.
Paused in debugger.

You can see that code execute has stopped, because if you look at the bottom, it says Paused on breakpoint. The line of code where it paused at is now highlighted in blue above.

All that's left to do now is inspect the values of the two values to see what's the problem.

Inspecting value of variables.
Inspecting value of variables.

And there's our problem! The value of divisor is 0! This means that JavaScript is now trying to divide by 0, giving us Infinity.

Clearly, if divisor's value is 0, then the problem is likely from getPositiveInteger. Upon closer look, you can see that because we are using Math.floor, there will be cases where the number is just below 1, therefore being floored to 0.

You can easily fix getPositiveInteger to work properly by using the JavaScript method Math.ceil instead.

	
    function getPositiveInteger() {
        return Math.ceil(Math.random() * 5)
    }
    var dividend = getPositiveInteger();
    var divisor = getPositiveInteger();
    var quotient = dividend / divisor;
    console.log(dividend + " / " + divisor + " = " + quotient);
	

Awesome!

You used breakpoints to inspect the values of the variables to then trace back the core issue to getPositiveInteger, then corrected the problem at the source.

	
    var bug = "squashed";