To use a debugger or to add a print statement, that’s the question!

Guy Hagemans
8 min readJun 20, 2023

--

As a developer, being stuck on code that doesn’t work is maybe the most stressful part of the job. Especially for a junior developer when you don’t have the confidence (yet!) you will eventually fix the issue.

So how to deal with that? I usually apply the following three steps:

  1. take a deep breath, relax, so you can think clearly,
  2. add a ‘breakpoint’ in your IDE,
  3. check what the code is ACTUALLY doing when using a debugger.

I’ve seen some heavy debates over whether you should use a debugger or use a print/console.log statement when trying to troubleshoot your code.

Some people swear by the use of a debugger because it is so much more feature-rich while others say ‘adding a simple print statement is super easy and fast’. There’s probably truth in both statements.

Personally, I really like to use a debugger because I truly believe it saves me so much time during the day while writing, testing and troubleshooting my code.

Wouldn’t you want to have extra time left at the end of the day, either to build more or to do something else?

In my opinion, all the bells and whistles the debugger provides make it so much easier and faster to identify the real issue.

There are probably scenarios where a simple print statement would be the most efficient tool for the job, however the debugger might very well be the right tool for more complex issues that you’re trying to solve.

Let me please show you the added value of the debugger and hopefully, it will help you a lot in the future while troubleshooting your code. It has saved me countless hours over the years.

The benefits!

The big benefit of a debugger is that you can see all the variables and their values when stopping the execution of your code on a breakpoint, instead of just seeing the value you printed. How many times did it not happen that when printing something to the console that;

  1. the value was exactly what you were expecting, but still the code is not working
  2. the value is completely different from what you were expecting and you still don’t know why the code is not working
  3. the value is not being shown because the function where you added the print statement did not execute at all
  4. the value you are printing has a malformed format, for example it is showing [Object object] or such a long string it doesn’t really help you.

The biggest hurdle to using a debugger is probably the setup time, or just the fact you haven’t used it before. I understand the stress that comes when troubleshooting your code. YOU WANT TO HAVE IT FIXED. So furiously adding print statements seems like the fastest way to do this. Sometimes or maybe even most of the time this is true, and I completely understand you do this.

Audience

Mostly I’ve taught the debugger to junior developers, but even medior and senior developers who haven’t used the debugger yet should probably read this. Give it a try!

Goal

The aim of this article is to show you it can be very quick to startup a debugger as well and save you time while troubleshooting an issue.

I’ll start with a how-to on debugging in Webstorm, but further down there is an example on VSCode (I’ll add this later!). These are very similar, I’ve found Webstorm to be easier to set up because a lot has been preconfigured for you already.

By the way, this is not a full explanation on debugging or the debugger. This is the most value you will get out of a debugger in 5 minutes. So that’s why I choose the below content.

Debugger quick intro

Note that I’m explaining the basics by using Webstorm, but don’t worry, the concept is very similar in VSCode.

Let’s take the following JavaScript code as an example (just quickly scan it, no need to fully understand it)

I found this code while working on a project on StackOverflow. Where would we be as developers without that website?

With JavaScript, because it is not typed, you can’t always be sure what the return type is. So what is the value of the variable check? To check this with the debugger, it’s a simple two-step approach:

click on the black space between the line number and the line of code to set a breakpoint:

a red dot appears, this is your breakpoint!

then right-click on the file and choose ‘Debug <filename>’, which in my case is ‘ipFilter.js’

Because it is a simple script, the debugger will very quickly execute the script

and show you the data. In this case, we can see the variable is of the type boolean and the value is true!

What is even cooler is that even though the output of the function is true, you can change the value during execution to for example ‘false’ and test that to see what your code would do. Simply click on the ‘check: true’ and hit F2 or click on the ‘Set value’ text.

Change the value to false and see what happens.

now hit ‘resume’ (which is option-command-R on a Mac and F9 on Windows). You can also find this button on the newly appeared ‘Debug’ panel:

Step over/into/out

Having your code stop executing at a breakpoint is nice, but being able to then see line by line execute is even nicer.

This way you can see for example if your code enters an if statement or identify where exactly your code exits because of an error.

To do this, repeat the steps from above (set a breakpoint and choose to execute the code using a ‘Debug’ session.

As you can see in this code, before validating the if statement, it executes the ‘isIpInCidrs’ function. If we want to see what is going on in that function, set a breakpoint on that line:

You now have two options:

Step over: By choosing this option in the debugger pane, you’re telling the debugger you are not interested in what the next function will do, simply go to the next function call. which, maybe a bit confusingly in our case, is the ‘ipReducer’ function which is called INSIDE the isIp4InCidr function. If this is confusing, don’t worry. When debugging, you can set breakpoints, step over or into and if it goes too far, simply restart the debugger!

Step into: this option makes more sense in our example, because this means the method that is about to be invoked (in our case the isIp4InCidrs function) is where the debugger will go next. Then when you click ‘step into’ again the debugger will move to the ‘isIp4InCidr’ function (cidr, not cidrS, sorry!).

Jump to Cursor

One more thing I would like to show is the option to ‘jump to cursor instead of setting breakpoints. Maybe after playing around with the debugger you’ve noticed that setting a lot of breakpoints can become a bit annoying because the code keep stopping at points where you don’t want it to stop. To have the debugger stop, even when there is no breakpoint, you can have it ‘run to cursor’ which means it will run the code until it reaches the line number that you’ve entered.

To do this, after starting a debugger session, don’t set a breakpoint by click between the line number and the code, but click on the line number itself.

In the example below, I have my mouse cursor on line 10 (sorry that the cursor does not show) and when you wait a second or two it will also show you the thumbnail ‘run to cursor’. The line also becomes a more transparent blue (depending on your theme).

When you click on the line, the debugger will run the code until it reaches that line as if there was a breakpoint and you can see the variables:

Evaluate Expression

My favorite function of the debugger is the ‘Evaluate Expression’ option. When dealing with more complex code, you might want to play around with the code and see what the actual value is when you change some of it. The ‘evaluate expression’ option is truly great for this. It will save you a lot of time, even during development.

In our code, you might have noticed on line 15 that we have the following issue:

In Javascript, you should never compare using the double equal sign because as shown it can lead to unwanted behavior. For example when you compare the value 10 with the value ‘10’ (string 10) using two equal signs, the output is true, while obviously these two are not the same because one is an integer and the other is a string.

To be sure the code is still doing the same as we want, we can quickly validate this by selecting the code we want to run and then right-click and choose ‘Evaluate Expression’

This opens up a window with the selected code. Click on the ‘Evaluate’ button at the top right bottom to execute the code. This is very powerful as you’re able to change the code and run it immediately. I’ve done this countless times while trying to get a .map function working. It saves you from restarting your application numerous times and seeing if this time you wrote the correct code:

There’s a lot more to explore in the debugger, such as:

  1. setting ‘watches’
  2. the ‘Toggle break on Exception’
  3. conditional breakpoints
  4. run configurations
  5. and much more

For a future article I will add the Visual Code examples. I’ll add these below here next week!

Hope you enjoyed reading this quick intro to effectively using the debugger! (This is my first article, so any feedback is very much appreciated!)

--

--

Guy Hagemans

Dad, Husband, Tech Enthusiast. Working for 17 years in IT as a consultant and architect and still loving it!