Skip to content

Debugging: A Structured Approach

Debugging is an inevitable part of software development. At its best, it’s a fun puzzle and a chance to learn. But it’s also easy to get lost.

It is about chasing the right lead – and it’s just as easy to go in the wrong direction and spiral into into a frustrating, time-consuming, and even burnout-inducing experience.

Common pitfalls include overlooking simple explanations, making false assumptions, or focusing on the wrong part of the system.

Here are some language-agnostic tips.

Meme: chatgpt makes human debugging more

Not everything applies to every problem, so use the ones that are relevant.

Try Again

Before diving deep, simply try again.

  • Make sure it's not a one-off issue.
  • Pay closer attention to what’s happening.
  • If the issue is complex, note down the steps to reproduce it.
  • If multiple errors occur, always start debugging from the first one.

Be at the Right Place

Ensure you’re working in the correct environment.

  • Are you editing the right code?
  • Are you looking at the correct app (e.g., production vs. staging vs. local)?
  • Is the app connected to the correct database?
  • Could caching be affecting the content?
    • Cache could be from network layers, build tools, or external providers.
    • Validate this by adding console.log statements, breakpoints, or modifying content/CSS.
    • Make a scene – try intentionally crashing the entire app.

What Changed?

Narrow down the problem by knowing what changed.

Consider how the problem came into existence:

  • Was the feature not implemented to begin with?
  • Or, more likely, was there an erroneous change made?
  • Did you install new packages or pull new commits?
  • Can you roll back and compare differences? Use git bisect.

Assume Nothing

Narrow down the problem by testing your assumptions.

It might not be your fault – third-party libraries or incorrect documentation could be the issue.

  • Are you referring to the correct documentation version?
  • If you suspect a library issue, do a quick GitHub issue search. It takes just a minute.
  • Have you tried restarting the app or your computer? – Yes, it can really resolve odd issues sometimes.

Reproduce Fast

Narrow down the problem and create a minimal reproducible example.

A minimal test case is necessary to:

  • Confirm when the problem is fixed.
  • Optimize validation to make debugging more efficient.

Consider:

  • Removing authentication, disabling validation, or hardcoding field values.
  • Writing a script that automates test execution (try Chrome's Recorder).
  • Ensuring the test case requires minimal manual interaction.

In some cases, you can brute-force by enumerating all possible solutions (for example, order of arguments, combination of flags):

  • Try each potential fix and execute your test script.
  • This might eliminate the need to dig into documentation.
  • Work backward once you know the final answer.

Bonus points if you convert it into a permanent test case.

Try Later

Stuck? Take a break.

  • Explain the problem to a rubber duck (aka a colleague).
  • Walk away, eat food, get coffee, and return with fresh eyes.

Happy debugging!

Created on 2023-06-27

Last updated on 2025-04-02