Debugging is part of a developer's job. It's a known fact that bugs happen and things break, so we put on our detective hat and try to hunt for the cause of the bug.
I've decided to share with you my experience with a particular problem and how I went from debugging to finally fixing the issue.
In opsdroid we use
pyyaml to load a configuration file written in
yaml that sets everything we need to make our bot work.
Recently pyyaml has released version 5.1.1 and introduced a few changes to the library. Unfortunately, these changes broke a few things and the documentation was only available for older versions of the library.
With this new version, the ability to use environmental variables and to include another
yaml file into the configuration file broke and we needed to fix the code if we wanted to update
pyyaml to the latest version.
Facing the problem
The initial stage of debugging can be pretty scary. You need to tackle the issue head-on, but you don't want to break things.
Sometimes, you will feel that you have no idea where to start and that will make you procrastinate to avoid the unpleasant task of tackling a problem.
In my case, I was afraid of touching the code since I didn't understand how the library worked and what exactly changed since the last time.
The task seems too great to take on at first, because the documentation couldn't offer much help since it was outdated.
I've decided to have a look at our code first. I knew that the code worked fine in the previous version(
4.2b1). So the issue couldn't be coming from the code but the changes that this new
After looking at the code, I headed to the pyyaml repository and looked at previous commits between version 4.2b1 and version 5.1.1. This was an attempt to get a glimpse of what changed and what stayed the same.
I've tried to change a few things in opsdroid code, but no luck.
I didn't have enough information and so I started my research. Going around StackOverflow and google to try and figure out if someone had the same issue as us.
There were a few questions in StackOverflow that offered a few solutions to the problem, but when I tried to implement the same solutions, the opsdroid code was still broken.
Pyyaml was updated just a few days ago so probably people haven't yet started updating their pyyaml dependencies and that might explain the lack of questions about these issues.
I had only one option, go deep and look into the pyyaml source code and attempt to figure out a way to fix the problems we were having in opsdroid.
Trial and error
The next stage of debugging was trying a few different things to see if they would fix the problem. I was switching between my editor (pycharm), the terminal to run tox to see if the tests were still failing and firefox with the pyyaml tab.
I needed to make changes to the code and figure out what was breaking, so I decided to copy the code that makes the environmental variables and the
!include and paste it in a new file.
Now I could run only that file and see if the changes that I added would fix the issue.
After a few hours, I was able to pinpoint the cause of the problem as to why the environmental variables weren't working.
In opsdroid, we are building a resolver for the yaml constructor - basically, we created our own yaml tag but didn't want to pass it all the time.
The resolver translates the code:
test: !envvar NameOfEnvVar
The new update was breaking our resolver, so now I needed to figure out how to fix it.
Back to the source code
Now that I had the cause of the issue, I knew what could help in trying to find the solution for the problem.
I went back to the pyyaml source code and checked the
resolvers.py file and looked up at what changed with the
Then went back to opsdroid code and tried to add the additional parameters to the function and attempt to run the tests.
All tests passed so I was pretty happy with it! Solving a problem is always an amazing feeling and the reason why I fell in love with code, so obviously being able to fix the broken code with little to no documentation was a bliss.
Before submitting the PR to opsdroid I decided to test the bot while using an environmental variable set and included yaml file.
I was happy to see that everything worked as expected.
Don't be afraid of debugging a problem.
It might be scary to tackle a big problem, but remember that breaking a big problem into small pieces will help you immensely.
Check the documentation.
Use the documentation to guide you. Sometimes it's worth going back to the documentation and reread something that you think you know how to do. Sometimes you just trust your brain or intuition but the docs will show you the best way to do something.
Dive into the source code.
If you are using open source and you think the problem that you are facing is because of a library. Maybe the latest update broke something.
Don't be afraid to dig deep and read that library's source code. It might sound scary but you will get important information and will understand better how the library works.
Test, fail, test, win.
Think about different ways to tackle the problem and test a different hypothesis. Sometimes you might think a problem resides in some place, but after testing other things you notice that the problem was actually coming from some other place.
In my case, I thought the issue was inside the constructor or the loader and didn't look into the resolver until a day had passed.
Sleep it off.
If you keep getting stuck. Try to walk away from your laptop or work on something else. Come back to the problem the next day and sometimes that helps a lot and you can see or think things that you couldn't before.
Ask for help.
If you are still stuck and have no idea what to do to fix the problem. Try to ask a colleague for help or StackOverflow.
Even if other people can't help you much because they haven't faced that problem, sometimes they can offer insight and offer you a different point of view and that might help you.