Below I will share some tips that have helped me in difficult moments.
The basic / well-known ones
Rubber duck debugging
Rubber duck debugging is a method where you explain your problem to anyone or anything (it doesn’t have to be a human). Then the solution magically stops playing with your goodwill and appears to you.
The ‘duck’ has no knowledge of your project, so you explain everything, questioning your assumptions at the same time. Ideally, you’ll suddenly have an enlightenment like, ‘Oh dear, it was in front of me, thanks bro, sorry for the interruption.’
Yet the duck was silent all this time, and that’s the magic part. :)
The good ol’ logging
When you have an issue to debug, you usually have a vague hypothesis of what might be wrong. It might be totally off from the actual cause, but this is another story. If you start putting logs in places where the error might occur, you may get to the point fast.
Even if you don’t, don’t remove the logs you added, as they might prove themselves helpful on a future issue.
I could argue why you should never reach this point, to add debug logs, as the logs should be there as part of the initial development. But Erik Hazard has already done the job.
More on logging later.
Breaking the points
A debugger is a great tool in your arsenal and a great help — if you know how to use it.
- First understand the problem
- Then make a couple of hypotheses about the root cause (and not the symptom)
- Set the appropriate breakpoints to verify or disprove them.
So don’t just put random breakpoints here and there. Have a routine and an ‘end’ in your mind when using it.
The less well-known ones
A few lines above, we spoke about the importance of logging. The command we usually use is
console.log('text'). But what if the output is more complex? Yes,
console.log handles arrays, too. And objects.
But what if I told you that you could spot the error faster because of some…beautification? That would be
console.table method and is demonstrated below
See what a nice overview you can gain from the layout? I highly encourage you to use it more, especially with iterables.
Break on events instead of lines
Let’s imagine the following scenario. A DOM element is changing intermittently and with wrong values, and you have no clue why. Which of the 29 functions that mutate it is being naughty? (Side note: Mutating is bad usually, but this is a topic for another blog post.)
Use the DOM change breakpoints. Every time the element is mutated, a stack track will be shown. Just like if you have put the correct breakpoints. You can find more details here.
If the bug you are working on is not performance-oriented, maybe this is overkill. But I still have to mention it (well, it may be a performance issue after all :) ). In Chrome and Firefox you can use the profiler’s built-in functionality to spot a bottleneck or just…see the functions that are executed. Boom :). Overengineering at its best. Please use this feature wisely. Killing a fly with a bazooka can have some weird side effects.
Thank you for reading this article. I hope you enjoyed it and learned something today. As always, I highly encourage to share your magic techniques in the comments.
Apart from the links cited inside the main text of the article, here are some more things I think are worth reading about the topic of debugging:
- Node debugging tutorial
- John Sonmez’s debugging guide
- Debug it
- Debugging: The 9 Indispensable Rules for Finding Even the Most Elusive Software and Hardware Problems
- Chrome debug tools
- Firefox debug tools
- ‘JSparty’ podcast and especially episode 30 from where I got inspired about this post and learned about `console.table`
Originally published on my blog.