Bugs and Errors

Bugs and Errors

Let's move to a new topic.


The mistakes that we have done while writing programs are called bugs. Most languages pointed out the mistakes automatically. But in the case of JavaScript, it's a little different.

It will let you do all the calculations without giving any typos. It is in the end where you will find that you did something wrong when you get NaN or undefined as a result. But there are some things that JavaScript complains about like not following the language's grammar.

The process of finding mistakes is called debugging.

Strict Mode

Even though JavaScript ignores almost all types of errors. You can make it a little stricter using strict mode in your code at a top of the file or function.

function usingStrictMode(){
     "use strict";
     for(counter=0; counter<10; counter++)


Now, this will throw an error that counter is undefined;

In general, what happens is that JavaScript creates a global binding and quietly uses it.

Putting "strict mode" in the code is very helpful in finding errors. It does some other things also. It disallows giving multiple parameters of the same name in function.


Some languages want to know the type of bindings before running it. But in the case of JavaScript, it does this while running the program, and even there is tries to convert values to another type it expects.

One thing you can do is write type comments so that you got less confused.


If the language is not doing much help in finding mistakes, you can use the trial and error method. But it is a time-consuming and ineffective approach.

Another thing we can do is to do Automated Testing. It is the process of writing a program to test another program. It's difficult to write test cases but once you do it, it's like gaining a superpower.

Tests usually a small labeled program that verifies some aspect of your code. Writing test cases is somewhat repetitive and awkward. But some software exists that helps to build and run a collection of tests that fails. It's called "test runners".


Once you know that there is some problem with the code. Next thing is to figure out the problem. Sometimes it's easier because the error message shows the specific line.

But sometimes it's difficult because the line shows the error that was caused due to some other mistake.

Let see the following program which is converting a whole number to a given base.

function numberToString(n, base=10){
     let result="";
     let sign= "";
         result=String(n % base) + result;
         n /= base;
     }while(n > 0);
     return sign + result;

So, when we run the program you will get some unexpected results. That's where we will know that there is some error in the code. Now, we need to know why and where.

Instead of making random changes in the code. You should analyze the code first and figure out why it is happening.

One way to figure out is to use console.log at some points to know what result is coming after a certain line of code. In this case, we want "n" to take values 13, 1, and then 0. If we put
in the starting of the loop. You will see the values of "n" something like:


Now we know dividing n by 10 is not producing a whole number. So, we can correct it by writing

n = Math.floor(n/base);

Error Propagation

Not all problems can be prevented by programmers. If you write programs for yourself you ignore things like invalid input, network failure, etc. But what if it is used by some user. So, your program should do something in response to these problems.

Suppose there is some function promptNumber that asks for a number and returns it. When you check the function you will put the number but what about the user?

What if he wants to just mess up with the function or wants to check that instead if he puts string then what will be the result.

One solution is to return special values like null, undefined, or -1.

function promptNumber(question){
     let result = Number(prompt(question));
          return null;
         return result;

Now, any code that calls promptNumber is reading an actual number, if not, must somehow recover either by asking the number again and again or by filling default value.


When some problem occurs in the function, it stops functioning and jumps to the place where it is known how to handle the problem. This is called error handling.

Exceptions are mechanisms that make the code run into a problem. It jumps out of not only the current function but also the callers, all the way down to the first call that started the current execution. This is called unwinding the stack.

Now what error handling does is, put obstacles between the calls to catch exceptions. So it didn't go all the way down. Once we caught the exception we can do something about it and address the problem.

function promptDirection(question){
    let result = prompt(question);
    if(result.toLowerCase() === "left")   return "L";
    if(result.toLowerCase() === "right")   return "R";
    throw new Error("Invalid direction:" + result);

function look(){
    if(promptDirection("which way?") === "L")
        return "a house";
         return "two angry bears";

   console.log("You see", look());
   console.log("Something went wrong" + error);

throw keyword is used to raise an exception. try and catch blocks catch the exception and handle it. After the catch finishes or try block finishes execution without any error, then the code beneath it proceeds to run.

Error constructor is a standard JavaScript constructor with a message property. In JavaScript environments, instances of this constructor also gather information about the call stack that causes an exception and called stack trace.

Error handling is very important in the code where the error occurs and where it handled.