Debugging a Bug Is Easier When You Stop Guessing
One of the biggest lessons I'm learning while building software is that debugging isn't about finding a fix as quickly as possible.
It's about finding the actual cause.
When something breaks, the easiest reaction is to change something and see if it works.
That can work.
It can also create three new problems.
The dangerous debugging loop
A common pattern looks like this:
Bug
↓
Change something
↓
Run again
↓
Still broken
↓
Change something else
↓
Now something different is broken
↓
Repeat
`
Eventually, you may fix the original problem without even knowing why.
That's not really debugging.
That's guessing.
Start with the symptom
Instead of immediately changing code, I try to describe exactly what is happening.
For example:
"The transaction isn't appearing after I add it."
That's much more useful than:
"The database is broken."
The first statement describes an observable behavior.
The second is already an assumption.
Those are very different things.
Follow the data
For an application like FinLedger, a user action may travel through several layers:
text
User taps "Save"
↓
UI
↓
ViewModel
↓
Business logic
↓
Repository
↓
Database
↓
Flow / State
↓
UI updates
If the transaction doesn't appear, the problem could exist anywhere along this path.
So instead of changing random code, I can ask:
text
Did the click happen?
↓
Did the ViewModel receive it?
↓
Was the transaction created?
↓
Did the repository execute?
↓
Was it actually stored?
↓
Did the query return it?
↓
Did the UI collect the updated state?
Now debugging becomes a process of elimination.
Logs should answer questions
Adding logs everywhere isn't automatically useful.
A better approach is to log information that helps answer a specific question.
For example:
text
Creating transaction: personId=42, amount=5000
Repository insert started
Repository insert completed
Query returned 3 transactions
Now I can see where the flow stops.
The goal isn't to produce more logs.
The goal is to produce useful evidence.
Don't ignore the simplest explanation
Another mistake I've noticed is looking for complicated causes too early.
Sometimes the problem isn't:
- a race condition
- a framework bug
- a database corruption
- a complex architecture problem
Sometimes it's:
text
Wrong ID
Wrong parameter
Wrong condition
Missing environment variable
Incorrect query
State not being observed
Before investigating something complicated, eliminate the simple possibilities.
Reproduce before fixing
If a bug happens only occasionally, the first objective should be making it reproducible.
Ask:
text
What exact actions cause it?
Does it happen every time?
Does it happen with specific data?
Does it happen after restarting?
Does it happen only in production?
A reproducible bug is much easier to investigate than a vague report saying:
"Sometimes it doesn't work."
The real skill
The more I build, the more I think good debugging is less about knowing every possible solution and more about asking better questions.
Instead of:
"What code should I change?"
Ask:
"What do I know for certain?"
Then:
"What assumption am I making?"
Then:
"What evidence would prove or disprove that assumption?"
That changes debugging completely.
You stop fighting the code.
You start investigating the system.
And that's a skill that applies far beyond Android.
Whether you're debugging an application, API, database, Docker container, or VPS, the principle remains the same:
Don't guess your way to a fix. Follow the evidence.
debugging #android #kotlin #softwareengineering #programming #development #buildinpublic
`
Top comments (0)