Today, I levelled up in debugging.
It’s easy to love something when things are going smooth. But then how to maintain this feeling when things are falling apart?
This is a story of error.
Part one: Error rising, slowly.
Two days ago was the first time, when one of my friends @HolidayCheck reported a problem, that his test coverage has decreased by some small percentage (we are keeping it at 100%). The advice was obvious: update your branch, reinstall all node modules, clear babel cache. This kind of things happens from time to time. You just get used to it in the world of JS development, where the pace of change is rapid.
Then we received second mention, that the problem was real. After that we found out that new git branches are also affected. This was not one time thing anymore. It had to be fixed.
Part two: debugging
My local environment was unaffected, so I had a good start. If you have some working example and the other one that does not, it’s easy.
You just compare, right?
My first idea was to list all the node packages and basing on the difference find the issue. When all 847 directories were listed in a different order, that idea has suddenly looked less interesting. I started upgrading some packages that might have affected our code, but the error persisted. So when the upgrade doesn’t work, the following thing to do is the downgrade.
I was a bit surprised that there was again no effect. I took a try at something else and checked the issues at our code coverage tool (Istanbul), unit test runner (Mocha) and finally code transpiler (Babel).
No luck, nothing reported there.
There were some times in my career when diving deep into the modules code allowed me to find the issue at some point, logging function after function. I spent next 2 hours on wandering through Babel and Istanbul internals trying to spot the problem following the stack trace.
Someone would have said that without a solution I wasted 2 hours.
Actually I’ve learned a lot.
I decided to go back to the differences in installed libraries. The code coverage tool had not been released recently, so my second shot was Babel.
It was released 3 days ago. Why have I missed that? The package was updated and around that time the error was found. Usually I would be mad at myself, but considering that it was waste of time, I just decided to keep this situation in mind.
The new version was tagged as 6.14.0. While I was checking what was listed within this package, familiar names started popping out, the ones I had seen previously in code. I found that one released fix for Internet Explorer in submodule dependency could have been the culprit of our test coverage failure.
I checked my local environment again and the package was not in the same version. We were not updating anything, so the package version should have stayed at the stable 6.13.2. Magic?
Some time ago I would believe that.
This time I decided to push forward.
Part tree: findings
One glance over sub dependencies manifest of babel library showed that they are not set as strict ones. If you leave the package version with the prepending caret, the following will happen:
^6.13.2 will match to the highest version in the range 6.x.x
6.13.2 will match only to exact version 6.13.2
As a result, even though we specified and installed Babel version as 6.13.2, after the official release, sub modules were updated to 6.14.0. The cause of the problem was still there. Nothing magical here (although we would like it to be magical, that would explain our problems and not harm our ego).
As a solution for that problem I’ve decided to not use all of the babel transpilation plugins. Native node ES6 support allowed me to drop faulty babel plugin. Obviously for production build everything has to be transpiled to support the older browsers and not yet available commonjs modules.
It’s always good to review what has happened and what we have been doing to solve the problem. The lessons learned will, for sure, improve my way of resolving issues like that.
What I could have done better:
- Thinking more before actually starting to search for the cause of error. Something has changed and the error popped out. I should focus on what has changed from the beginning.
- Being more analytical. Diving into the code was not a good choice in this particular situation.
- Less anger. Embrace the failure and keep pushing forward.
What I am proud of:
- I stayed focused on the job. I jumped away to social media couple of times, but after becoming fully aware of why I had done that, I’ve got back. (It’s easy to get distracted while being stuck with the job or during
30 second application build)
- I was truly curious about the problem. I’m sure that this helped me a lot in avoiding situations like “abandon the ship, let’s start the weekend”.
Got similar debugging problems? Share your story!