How did that weird bug come in the code

 · 8 mins read

three brown planters on concrete surface by Fancycrave On Unsplash

Ever Spent an entire week to find out where the bug is?

Ever Wondered how this bug was never caught during the development phase?

Then this post will definitely be useful for you 😃

This post will explain how to find the source of a bug in a code, and also about best practises while writing code 😃

What type of bug is that hard to find?

Let’s say that the code has 100000 lines of code.

Now the Code does not throw any error when it’s run. So that’s good 😃. No-one likes errors right?

Now one of your customers reaches out to your development team and says that they are not able to perform some action in your application.

Now you will need to find out why the code is doing this. But as I had already mentioned the code does not throw any errors.

Now, the question is how do you find out what went wrong in 100000 lines of code 😕

An error doesn’t look so bad now right since it at least gives you some information on what might be wrong 😃

Now, how do you find this bug?

Debugging to the rescue 👍

Debugging

Debugging

“selective focus photography of woman holding clear glass ball” by Anika Huizinga on Unsplash

What is Debugging?

Well, as the word says it is De — Bugging. Debugging is the process, where you go over the code to find out where the bug is.

What tool do you use to debug?

You guessed it right. It’s a debugger 😃

Depending on the language the code is in, you first need to choose the right debugger tool. If you are using Eclipse, it automatically comes with java debugger. If you are working with javascript, you can use the debugger which comes with any web browser and so on.

What exactly do you do while debugging?

Using the debugger, you can set checkpoints in your code and then run the code in debugging mode.

Let’s say you set a checkpoint in line 10 of the code. Now when you run the code, the code will stop running and pause at line 10.

Now at this state, you can do things like inspect the variables in the code and see if anything seems odd. You can check what values the variables contain. You can verify if the content of an array or object is proper and so on.

If any variable has a weird value, then you have a possible suspect 😃. Using this information, you can set checkpoints wherever that variable is present and keep repeating this process until you find the true source of the bug 😃

Debugging seems pretty easy, what’s the catch?

The catch is you have 100000 lines of code. Where do you put the initial checkpoints?

It’s possible that the code was written by multiple developers over the years and no single person knows the whole codebase. So how can you know where to put the initial checkpoints?

Well, the truth is this

In order to debug the code easily, the code must be written in such a way that it is debuggable in the first place.

In order to debug the code, you will need to understand what the various parts of the code are doing on a very high level.

But to understand the code, the code must be written keeping some best practices in mind. I will be mentioning some of the best practices here.

Making the code modular

Modular

“four person holding assorted-color jigsaw puzzles inside room” by rawpixel on Unsplash

Simplicity is the Ultimate Sophistication — Leonardo Da Vinci

Imagine having a single file with the entire 100000 lines of code. It is impossible to read such a code.

Instead, it is a good practise to break up the code into multiple modules so that each module does a specific task.

This idea can be expanded as well. First, the application can be divided into a number of bigger modules, and each bigger module can be divided into a number of smaller modules.

For Example, Let’s say you are building an e-commerce site. The application can be divided into bigger modules as follows.

  1. Login/signup page
  2. The homepage
  3. A shopping cart
  4. Search option
  5. Recommendation option and so on

These are bigger modules since they perform a big task. This can be broken into a number of smaller modules

For example, Signup page can be broken down into

  1. A module for reading user input
  2. A module for validating user input
  3. A module to check if the username already exists in system
  4. A module to check if password is strong and so on.

Dividing the code in this way makes it more readable, and helps make the code more debuggable.

Right naming conventions

Naming Conventions

“signage on post during daytime” by Adi Goldstein on Unsplash

Let’s take the below code as an example

function abcd(c) {
    //Some main logic here
    return z;
}

We have no clue what the above code is trying to do since it does not have a proper naming convention. Let us rewrite the code

function validateUsername(username){
    //Some main logic here
    return isValid;

}

This code makes more sense than the previous one. This code is trying to validate the username.

Having proper naming conventions makes the code easier to read. This, in turn, makes it easier to debug the code.

Documentation

Documentation

“person typing on brown typewriter” by rawpixel on Unsplash

So you have finished writing your code and everything is working. Great 😃

Now it’s time to write documentation 😕

I know, I know. You may be thinking “Hey the code is working, why document it”. Well, documentation is what ensures that others can understand what code you have written.

In fact, if you look at your own code after 6 months, you will have no clue what it is doing without the right documentation 😃

Consider the code below.

function cleanData(data){
    //cleaning logic
    return cleanData;

}

In the code above, naming convention is good. But what is the above code trying to clean?.

/**
* Function to clean input data
* 
* 1. If any of the rows have null, 
*    replace with 0
* 2. Ensure that 'id' value of a row 
*    is not null. If it is, then 
*    skip row
*
* @param {Object} data  : Input Data.
* @return {Object} : Returns an object 
*                    which contains clean 
*                    data.
* 
*/
function cleanData(data){
    //cleaning logic
    return cleanData;
}

The code above has documentation. Now it is somewhat clear what cleanData function is doing( This documentation can be made better). You may feel the documentation is bigger than the code itself here 😃. For smaller functions, you can use a simple form of documentation. But for bigger functions, a proper documentation is needed.

I know it’s an extra effort to write documentation. But you will appreciate documentation in the long run 😃

Documentation helps in debugging because it helps in understanding what a piece of code does, without going through the code in depth.

Unit Tests

Unit Tests

“electronic circuit boards near tester” by Nicolas Thomas on Unsplash

For example, consider the following code.

function sum(num1, num2){
    return num1+num2;
}

This function calculates the sum of 2 numbers and it is working fine.

Let’s say someone changes the code above to the following by mistake.

function sum(num1, num2){
    return num1*num2;
}

Now the code is wrong since it is returning num1*num2 rather than num1+num2.

Unit tests catch such issues automatically without someone manually reviewing the code.

So the Unit test is a piece of code which will test the sum function by giving different values for num1 and num2 and see if the right output is coming out.

Unit tests ensure that such minor issues are caught during the development phase itself. If these issues are not caught during development, then they can pile up and create a major bug in Production. So it is always better to write Unit tests. 😃

Hope this post was useful. Coding best practises definitely help a lot in the long run, and they definitely make debugging easier. 😃

Feel free to connect with me in LinkedIn or follow me in Twitter

This post was originally published in medium.com