As a developer, a major part of your day-to-day responsibilities will entail needing to deal with bugs, finding a problem, replicating it, and fixing it.
It’s much easier to write code from scratch, looking through old code, understanding it and making it better is much more of a challenge.
We have tutorials that teach us language best practices, how to use design patterns, dealing with code smells, writing lean, maintainable code; However, this crucial aspect of our duties is often overlooked.
The purpose of this article is not to tell you how to fix your bugs, it’s describing the process you will need to go through to find and diagnose the problem.
It’s true, occasionally you will have written the code that has caused the bug in question! Time to investigate what went wrong! Now it’s simpler if you wrote the code, as you’ll know where to look.
But what if you didn’t?!
Tip: Your mindset needs to be that of a detective.
How to know where to start?
Yes, this is hard! Someone raises an issue or sends over a screenshot. A stack trace drops into your Inbox! What does this all mean? How can you use this information to determine where the problem originated from?
Let’s look at the steps I would take.
Step 1: Replicate the issue
The first thing you need to do is replicate the error. A LOT of errors that get logged are down to incorrect configuration, network problems or browser related, so this is an integral part of debugging.
Tip: Get all the configuration information you need before starting, and the steps to reproduce!
Trying to fix a problem without replicating the error is a task of futility. Unless you can see it not work, you will never know if the change you make will actually fix it!
Step 2: Find an entry point
With the information you have, try to find a way of using that to get into the code.
Problem: Form Error
Say you have a screenshot of a form with and an error message displayed. How can you use that to get you to where you need to be?
When investigating a problem, there will be two avenues that you will need to inquire of. Is there a problem on the client side either in the JavaScript, CSS or HTML; or the problem is on the server side; the backend code, where your data/database and infrastructure lives.
Step 3: Rule out the possibilities
If you’ve ever played Guess Who you’ll have a good understanding of what I mean. You have your suspects, now it’s time to whittle them down!
Tip: It’s all about taking a systematic approach.
Here, we’d probably want to start with the client side, as that is our entry point, and where we can inspect how the error. We’d want to verify whether the form is doing the checking within the browser or sending some information to its pals on the other side!
In comes developer tools, known to many as the magic F12 key! Here you can view and access the DOM, the underlying HTML, and JavaScript on the page.
If you’ve never used Developer Tools before here are two great intros into what’s available. Even if you know it, I’d highly recommend this first short video that gives a quick refresher of 12 tricks you may have missed.
Tip: Note the Id and CssClass names of the suspected tags and find the files where they are in.
Using this approach will give you an avenue to check what was happening and where to focus your attention on next. Inspecting the tags and elements, extracting the Id and CssClass names will mean that you can delve into the source code at the precise location where the problem is occurring.
Generic client side gameplan
- Check the console for errors
- Inspect page finding the handler associated with the issue.
- Add breakpoints so you can view the parameters being passed, and view the call stack in case those values came from elsewhere
- Search in source for tags or handlers to be able to change the relevant files. Add log lines in order to aid visibility.
- Test your change.
- Repeat until done.
Tip: If using Typescript or if your Js is bundled add a debugger; line so that your browser will automatically break at that point when your code executes, this is a great way for finding where those files have been combined to.
Step 4: Bad data in or bad data out.
Problem: Data Display Error
If your problem is with data rather than validation, you will need to figure out whether the data is being saved incorrectly or being displayed incorrectly.
If, for example, you have a label on your page which should display your name, but it’s showing your age.
You need to find out whether you are using the wrong field/value to display the label, or the value is being retrieved correctly but saved incorrectly.
A problem of this ilk can be harder to pinpoint, as you do not know where that data is coming from, similarly to our first example, find an entry point, and follow the code up to where data is being loaded. Now you can check whether this data is incorrect at the source!
Tip: This may be an application lifecycle hook such as Page Load or Init.
Backend gameplan
- Find where the data is being retrieved from, which table, proc or function is being called to display that value.
- Query the database using any unique identifiers to filter down the results.
- Depending on the outcome, you will have two possible avenues.
- If your problem originates elsewhere; when the data is saved.
- Or when it’s being displayed.
- If displayed, circle back to the client side gameplan else…
- Find all possible routes to inserting data into that table/store, and whittle down which one is causing the problem.
Problem: The Stack Trace
The Stack Trace
Sometimes you’ll be presented with a giant wall of text also known as a Stack Trace. The stack trace looks scary, initially comparable to that of a towering wave. But don’t worry as there will be lots of information about libraries and binaries you don’t care about, and probably never knew existed. In 99% of cases these will not be the problem, so find the lines that equate to the code that’s yours!
If you receive a stack trace, you are actually in a very strong position. It tells you that an error has occurred and exactly where it was falling over. This makes your job much easier. Look for the method names being called, the files involved, and the line numbers to find the source of the problem. Then, depending on the problem, follow the relevant game plans listed above.
Tip: Find the first time your code was called, and start from there.
Here’s a great look into the intricacies of the stack trace and how to find the bits relevant to you! https://alligator.io/js/stack-trace/
Not getting anywhere?
If you’ve already:
- Replicated the error?
- Used Google to rule out any arbitrary problems?
- Found the source code you “think” is causing the problem?
- Added in debug points, print statements, console.log lines to confirm your assumptions?
- Made some changes, and the bug still is occurring?
- Smashed your head against the desk multiple times??
Ok, so it’s probably time to pull someone in to help. After spending an hour or so, if you’re struggling to make progress find someone to talk the problem over with, sometimes just discussing the problem will give you new leads or a new road of inquiry.
Art comes with practice
As you can see, finding the root cause of an issue is hard, there are lots of potential routes, and quite often numerous red herrings or dead ends. Finding the optimal way of tackling each issue is a valuable skill in your arsenal. Over time, you will instinctively know where to start your search and save some time. Saying that, assumptions are usually a bad thing when looking into the code, it’s always best to see what is happening, rather than what you think is!
I’d love to know if you have any tips for your fellow developer?
Alternatively, what’s the biggest mistake you can make when starting out looking at a problem that is raised?
Do you write unit tests to cover every bug you encounter???
Additional Reading
- https://simpleprogrammer.com/effective-debugging/
- https://www.codementor.io/mattgoldspink/how-to-debug-code-efficiently-and-effectively-du107u9jh
- https://hackernoon.com/how-to-debug-any-problem-ac6f8a867fae
- https://alligator.io/js/stack-trace/