DEV Community

loading...

A silly bug that sneaked into production

rahul_ramfort profile image Rahul ・2 min read

So, this is what happened.

I was in the middle of some task and suddenly had to make a context switch to a different task that I had pushed earlier. I forgot to handle a failure case and the code went to production already. But the change was pretty simple.

I had to add a condition to some existing code that looked similar to this,

Good code

Consider this is the condition that I had to add.

Buggy code

With this done, I asked myself if I should test this out before pushing and the genius in me replied that this was a simple change and I could go ahead without any testing. I also had this pre-commit hook to save me from any syntax errors. So, I felt I was pretty much covered and good to go.

I pushed it, the pre-commit hook passed, shipped to prod as well 🚀 and I went back to my other task.

Within a few minutes, our error monitoring tool started showing even more errors, this time 100% of the requests were failing compared to the negligible 1% requests that were failing earlier.

Guessed what could have gone wrong already? Kudos to you.👏

If not, here's the error that will help you find it.

TypeError (class or module required)
Enter fullscreen mode Exit fullscreen mode

If you think that MyObject is not a class or module, you're wrong. Because that piece of code was already in production and is syntactical fine.

So what could have gone wrong? Give it a moment to look into it again.

Okay, here it goes, I didn't tell ruby explicitly about the execution precedence and as a result, it considered MyObject && (self.some_validation? || self.other_validation?) as the argument to the method self.is_a?.

So the result of MyObject && (self.some_validation? || self.other_validation?)? is either one of these.

MyObject && true #true
MyObject && false #false
Enter fullscreen mode Exit fullscreen mode

As a result, the argument to self.is_a? is now a boolean,

self.is_a? true
Enter fullscreen mode Exit fullscreen mode

which throws the error, * TypeError (class or module required) *

The fix is pretty simple though, just add a bracket to let ruby know the precedence of the execution.

Fix for the bug

Days like these are bound to happen and it just makes you more humble and makes you learn the nuances of the language.

Discussion

pic
Editor guide