[Part 1] Proper NodeJs Debugging with Visual Studio Code

So you just console.log everywhere whenever you have a bug yeah? It’s time to stop that bad habit.

Bello Mubarak
Hacktive Devs
7 min readMar 19, 2019

--

This is the first part of our debugging series. Watch out for the second part!

In this short piece, we’ll be looking at some cool features of Visual Studio Code (VSCode) that makes proper debugging an easy and enjoyable task (pss: debugging can be a pain in the ass).

This article is in three parts:

  • Introduction
  • Getting familiar with the VSCode debugger interface
  • Debugging a NodeJs code snippet

So what exactly does proper debugging mean?

According to Techopedia, debugging is the routine process of locating and removing computer program bugs, errors or abnormalities, which is methodically handled by software programmers via debugging tools. Debugging checks, detects and corrects errors or bugs to allow proper program operation according to set specifications.

Quoting from the piece up there, “handled by software programmers via debugging tools…”, your bugs should be debugged by a proper tool. Now, you can argue that console.log fits as a tool for debugging. Of course, you are right! But you’d have noticed I’ve been emphasizing the word ‘proper’. console.log works right, but it’s not really the proper tool to use. Here’s why…

Even though console.log gets your small errors fixed, it has a major downside of easily polluting your codebase. To fix a bug on a single line of code, you probably will have to attach several console.log calls just to track your program execution flow. If by chance you notice that you’ll need to inspect your program at some other parts, you’ll need to add another console.log expression, and probably restart your program/dev server.

Don’t be like Drake here, use a debugger.

Other than the ease at which console.log pollutes your codebase, you are also missing out on a lot of options that good debugging tools provide — options that will save you unnecessary trouble.

So, enough of the introduction.

Let’s take a look at the VSCode debugger interface and get familiar with some of the features.

Visual Studio Code in-built debugger interface

To launch the VSCode debugger, click on the “Debug” icon in the Activity Bar. Once opened, let me introduce you to some important sections of this debugger interface.

There’s a top bar “Debug” option in the menu bar that has the most common debugging commands and configuration settings.

Debug option in the Menu bar has the most common commands

Also, in the Debug view sidebar, there are sections such as Variables, Watch, Call Stack, Breakpoints, and Loaded Scripts (pops up during a debugging session). These sections are important because they provide information about your current program execution:

  • Variables: shows the values of all the variables in the current local scope, in a closure or in the global scope! Phew!!! That’s a lot. With this, you need not to console.log() every variable in your program just to know which one is undefined .
  • Watch: lets you execute expressions using the currently defined variables in your program. You can run valid javascript commands to, for example, check the type of the variables or the length of arrays. The important thing is that you have access to the variables defined in your code, and you can do anything you want with them.
  • Call Stack: keeps a log of your program execution order, so you can track the execution flow. This is particularly helpful when your program is running in an unexpected order.
  • Breakpoints: One of the most important feature! Breakpoints let you tell the debugger to pause execution at some points you declare. This is what you should use in place of console.log to inspect values or function calls at specific points in your program. Breakpoints in the VSCode editor margin are normally shown as red filled circles.
  • Loaded Scripts: shows all the scripts loaded into the current scope, including external modules.

Another important section in the Debug view is the floating Debug Toolbar that only pops up when you start a debugging session.

Debug view toolbar
  • The first six-dotted icon is for dragging the toolbar.
  • The second icon (Continue / Pause) is used for continuing/pausing execution.
  • The third icon (Step over): for executing code line by line, skipping functions.
  • The fourth icon (Step into): for executing code line by line, going inside functions.
  • The fifth icon (Step out): if already inside a function, this command will take you out.
  • The sixth icon (Restart): for restarting the debugging session.
  • The last icon (Stop): will stop the debugging session.

Now let’s make use of these features in debugging a NodeJs code snippet.

The code snippet is a message decoder. The errors may seem obvious, but the idea is to demonstrate debugging.

Running the above code with base64 installed gives an error:

message is not defined on line 5. Knowing the current line giving the error, let’s set up a VSCode debugger. In the editor margin(where the line numbers are shown), go to line 5 that contains the error and click on the left side of the line number. This will add a breakpoint to the current line and will normally be shown as a red filled circle.

Breakpoint added on line 5 is indicated by a red filled circle

With a breakpoint set, now click on “Start debugging” either in the top Debug menu bar or at the top part of the Debug view sidebar to start the debugging session.

Debugging session started. Execution paused on line 5

Because a breakpoint is set, execution is paused on line 5 so that we can inspect all the defined variables at that point and determine why message is not defined, before we resume the code execution.

Take a look at the Variables section. The local variables defined are this and massage. I bet we were expecting message instead of massage . Now we know we are making a typographical error, and we can go ahead and fix that. After correcting that, click on the Continue button to resume execution. The debugging session should end now because we have just one breakpoint set.

Now run the code normally again, with the breakpoint still set, to verify that it is now working correctly. Execution will pause on that line again, and now we can see that message is now defined. Click on Continue to resume execution. In the Debug Console that pops up at the bottom of the window, you should see that the decoded message is now logged to the console. Just what we want right?

Now, you should also notice that execution is paused on line 5 again, and we are getting the same message when we should be getting the next message in the list of messages. We have no idea why this is happening, so let us continue the execution in steps. Instead of the Continue button, now click on the Step Over button to run the code step by step.

If you continue clicking on Step Over, execution will at a point be paused on line 29 in the while loop. Now we know the reason why execution is being paused repeatedly on line 5 — the while loop! Inspecting the local variables in this current scope, you should see that base64, count, decodeMessage, exports, module, require, among others are defined.

One thing to notice is that count remains 0 no matter how many times we step over! It has finally dawned on us that the value of count is not incrementing, thus the reason why the message is not changing! So to fix that, we add a line to the end of the while loop:

count += 1

This will increment count and ensure that we are getting the next message in the list of messages. Now if we step over, we should get the next message in the list and the rest of the code should work fine.

SUMMARY

In real projects, you’d want to follow proper debugging techniques so you can avoid the stress that comes with several console.log calls. Make use of several breakpoints instead and inspect all variables at once instead of “console.logging” every variable!

Feel free to drop comments and questions below, thank you for reading and watch out for the second part of the series.

--

--

Bello Mubarak
Hacktive Devs

Python 🐍 | Js Front-end web dev 😇💪💻 Computer engineering student at OAU **Bio link: https://about.me/mubarak-bello