Beginner Web Developer Series: Debugging (for web developers)

This is part one of five in my Beginner Web Developer series. It's a series of posts targeted toward people who want to be web developers. These people could be high school or college students as well as people looking for a new career. The series is not focused on writing code, but rather, the countless other things you must do as a web developer.

If you know how to debug a web application, you'll add a ton of value to your team and to your company. Simply knowing how to use the developer tools in your web browser will get you a long way. Even if you're only responsible for QA (quality assurance), being able to investigate what's happening with an application is a great skill.

Image Credit: Michael Himbeault (http://flic.kr/p/7NFTF6)

Image Credit: Michael Himbeault (http://flic.kr/p/7NFTF6)

You don't learn how to debug overnight. It's a way of thinking developed year after year. After awhile, you'll develop intuitions about bugs to help you solve them quickly. This will help you work faster and move on to other important things. Simply put, if you put in the effort to debug, you'll improve as a web developer.


Interpreting bug reports

Whether it comes from a customer or a colleague, you'll have to field a lot of bug reports as a web developer. Knowing how to interpret these bug reports is a key skill you should be growing over time. Asking the right questions is key to success.

You'll be receiving bug reports from non-technical people. Remember, they don't know everything about your application, so they're trying their best to explain their problem. Also, they might rely on your application for day to day operations and the bug they're reporting is making their day rather frustrating. As frustrated as they may be, you should stay calm.

Since most people will be non-technical, you'll often need to politely ask for clarification. What browser are they using? What page were they on? What were the exact steps performed before this happened? Some of these questions may sound simple on the surface, but they'll be difficult to answer. Remember, non-technical means the person isn't a developer. They aren't trying to trick you - if you need more clarification, ask again. Even better, ask for a screenshot.

Gathering this information can be tough for both you and the customer providing it. You must learn how to bridge this communication gap. Try to refer to things in terms they'll understand. Keep note of the way you communicate to figure out what works and what doesn't. Screen-sharing and/or screen recordings can be a great tool when used correctly.

Once you think you have enough information, reproduce it yourself. Keep track of the steps you took to reproduce it. Once it's fixed, you can use those steps to double check your work.

If you can't reproduce, it could be a problem that only exists on a certain browser. CSS and JavaScript can easily behave somewhat differently on each browser. Use Google to search for similar issues.

Screen Shot 2015-12-16 at 1.48.12 PM.png

If you still can't reproduce the issue, check your copy and any error messages you might see. Maybe the customer is getting confused. Your company may need to tweak the way things are worded on a page. Although these aren't bugs in the software sense, these are bugs within the user experience. These can be especially frustrating. The customer wants to do something (like reset their password), and the application is telling them they can't. Did you know? According to the Gartner Group, between 20% to 50% of all help desk calls are for password resets.

After you've properly interpreted the bug report and reproduced the issue, you're ready to work toward a fix. Even if you aren't assigned to implement the actual fix, performing the next few steps will prove invaluable to the person eventually assigned to the problem.

Checking for recent code changes

The easiest place to look is the latest release. Find the most recent deployment to production and start looking through what changed (if you use GitHub, you can perform a diff to see changes). Take a look at the developer responsible for most of the changes and ask them about the issue. They'll be most familiar with the code and chances are the code will still be fresh in their mind.

Remember, you aren't trying to assign blame. You're trying to investigate the issue. Pulling in the right people is key. The right person should have an idea of where to look.

If you're on your own and the release was large, your best bet is to look through each commit. If you're not yet familiar with version control, a commit is a set of changes to the code. It's like a before and after photo.

If the release was small, you'll likely want to look at everything at once. If your team uses pull requests (a group of commits with a related discussion), check that. Use the pull request to see all changes made since the last release.

Building a timeline

Not all bugs are new. While it's important to first look at the most recent changes to the application, you may have some bugs that have existed for some time. These issues are usually not critical, but still result in undesired behavior. Either way, it's still important to be able to identify these elder bugs.

Since you're likely using version control, you should be pulling up the commit history of the application in question. Your best tool will be talking with other developers and looking at the history of changes. If you know the general section of code which is causing the problem, you can look at the history of changes to that section. GitHub has a tutorial about seeing the difference between files.

Once you figure out when the bug was introduced, your first reaction shouldn't be to tell the developer responsible for it. Try to figure out the exact date and time when this change hit production. You should be able to determine when it was released and what particular release it was introduced with. Keeping a history of deployments to production is considered a best practice in the industry.

A timeline of a bug is important for many different reasons. It's particularly important to understand the impact of the issue. If it's existed in production for over a year, chances are there isn't much impact. If an issue is high impact, it effects a lot of people and your customer service team will be bombarded with incoming tickets from concerned (and some pissed off) customers.

If the issue isn't high impact, you should understand the value of a fix. It may not be that important to your company and you should classify it as such. However, changing gears is important. If an issue is determined to be high impact, you should react as such.

Proposing a solution

Understand the impact. Do you need to perform emergency maintenance? Do you need to forward this to every developer so they can stop what they're doing and work on it immediately? If so, you don't want to release a quick fix only to see the issue grow or to see an entirely new issue pop up. Most often, taking the time to properly fix a high impact issue is much more important than the speed in which you fix it. In the typically long timeline of an application, one bug is nothing but a blip on the radar.

Try not to take on extra pressure while fixing a high impact issue. While you don't want to spend days patching up a critical bug, you don't want to allow someone to drive you to make more mistakes. If you don't feel comfortable in what you're doing, say it. It's your responsibility to admit what you don't know.

If you get assigned to fix the issue, use your ability to reproduce it. Only change what's absolutely necessary. You don't want to introduce new and unrelated issues. You also don't want to work on other features, tweaks, or anything else. Stay focused on the issue and only that issue. After you implement a fix, follow the same steps you used to reproduce the issue. If the issue remains, your fix wasn't a fix.

Why did this happen?

After fixing the issue, reflect.

Try to understand the bug. Was it a typo? Was it an honest mistake or a misspelling? Is it something that should have been caught in a code review? Was the logic in the code completely wrong? Is there a test you could write that would've caught this issue before it hit production? Sometimes you might ask, how did this ever happen?

It's ok to ask these questions as long as you don't make it personal. Reflecting on a bug isn't a shaming session. It's a chance to learn and improve what you do in the future. You may not have all the answers - feel free to encourage the other developers on your team to discuss it.

If you're the developer responsible for the bug, take full responsibility for it. Don't try to pass it off on others. No matter what, stand up for yourself if need be. If other people on your team are criticizing you, listen but remind them you're only human. The best thing you can do is focus on getting better. The good thing about mistakes is we learn from them. Chances are, the bug will stick with you and you won't make the same mistake in the future.

If you're not responsible for the issue and simply reviewing it with your team, don't shame the responsible party. Empty criticism doesn't help anyone. Be helpful. Help them get better. When they get better, your team gets better.

Bonus: Developer tools (Chrome)

For sake of simplicity, we'll stick to Chrome and its phenomenal suite of developer tools. Here are some of the things you can do:

  • Why is this link a certain color? (Inspecting CSS)
  • Does this text look better if it's slightly larger? (Tweaking CSS)
  • Why is this button not doing what it's supposed to do? (Checking for JavasScript errors)

If you're using Google Chrome, right-click anywhere on a web page and click Inspect Element. This will open the developer tools (which look something like the below image).

google-chrome-developer-tools.png

When I started writing this, my intention was to write this section on my own. I had a vision of a section of animated gifs and some text. Then, Dev Tips Daily popped up in my Twitter feed. I don't think I could do a much better job, so I'm linking to my favorite ones.

Learn how to search by CSS class. Quickly change an HTML element. Copy the response of something on the network tab. If you want to become a power user of these developer tools, I encourage you to signup for their daily email. You'll surely learn something new every day.

Resources


Need help integrating the systems you use? Get in touch with us.

Announcing the colorizable gem

We were working on a project recently where we needed to store colors and convert those colors to different formats (we build custom iPhone apps for studios that use Tula Software). Rather than jump right in and write our own code for this, we looked around a found a great gem called color.

We were further inspired by one of my favorite gems, money-rails, which allows you to simply mark an attribute as "money" and it does all the work for you (formatting, currency, converting to dollars if stored as cents).

We threw together a similar gem called colorizable. Colorizable gives you all the power of the color gem, turned on with a simple "colorize" statement.

Is this thing on?

One of the things I've noticed is that once you're on a roll with writing it's much easier to keep it going. Likewise, take an extended hiatus and next thing you know it's been 6 months since your last post.

I've been writing very regularly on the Tula blog, but haven't been writing here as much as I'd like. Time to change that, so here's a post to unclog the tubes.

More better to follow soon.

If you're a small team with no sysops guy, PaaS will save your SaaS

We've recognized it time and time again.

Just this past week, the GHOST issue (glibc gethostbyname buffer overflow) popped up. Many people all over the world were scrambling to patch their servers. Large companies and small companies alike, they all had to deal with it one way or another.

As usual with anything like this, we looked to Engine Yard for an update. Our app servers and database servers are hosted on Amazon EC2 and Engine Yard is a PaaS that sits on top of it. Engine Yard provided their customers with a timely update about the issue and how they planned to solve it.

They've gained our trust over time, so we simply stopped worrying about it and waited until they released their patch. Once they released their patch, we followed their detailed instructions and applied the patch on our own schedule. As with something as far reaching as GHOST, it wasn't super easy, but we made it through and we're now the proud owners of patched servers and relaxed minds.

With our servers hosted on vanilla EC2 and without a talented, dedicated sysops guy, this situation would have been a nightmare for us. Instead of shipping new improvements to our product, we would've been at a full stop investigating, experimenting, testing, etc. etc. We don't consider ourselves experts when it comes to managing servers. While most of our engineers have plenty of experience with Linux, we don't want to mess around with sysops.

We want to focus on what we do best - releasing software.

Do we always want to be afraid of Chef recipes, server updates, automated provisioning and the like? Certainly not. However, at this point, we don't want to rely on it as a core competency.

By not hosting your product on a PaaS, you're designating sysops as a core competency of your engineering team. If you don't, you'll pay the price.

One day, you might pay the price in security. You won't have anyone watching out for security issues and your servers will go unpatched, open to abuse.

Next time, you might lose a week or two on scaling. You won't have a proper, load-balanced cluster. Your servers will be on fire. Your engineering team will be firefighting for days. They'll have to learn Chef, haproxy, and countless other things they haven't been spending time with.

You'll most definitely be paying the price during your day-to-day operations. Your deploys will cause downtime. Deploys will be frowned upon. Your engineering won't be happy. They'll have to stay late to deploy something that should've been deployed as soon as it was ready.

Companies that manage everything from deployments to automated scaling are saying, "Hey, sysops is important to us. It's a core competency of our business. We get huge value from it." If you're trying to imitate them and you don't have anyone focused on sysops, you're not ready. Companies like Facebook get huge value from their data centers. They need them. If you're not ready to hire someone with a specific focus on the subject, you don't.

The argument for small businesses and PaaS is a numbers game - in a good way. You might think it's more expensive at first, but it's not. Here's an easy list of things we receive from Engine Yard:

  • Someone to talk to when a weird problem pops up
  • Someone to be on the lookout for security patches
  • Someone to ask about scaling
  • Someone to alert us about server maintenance on EC2
  • Someone to improve our server configuration

That's just the short list. When you start to think about the amount of value you get from a PaaS, it's enormous. It's far cheaper than what you would be paying someone in annual salary to be your sysops guy.

Spring cleaning your code base

Code rots over time. While you're busy adding new features to your app, you might be forgetting to throw out the old. This is a friendly reminder to sweep out the garage and get rid of the things you don't need.

You don't have to scour through every line of code to get results. Here are some areas you may be able to score a quick win.

Move any third-party assets in `app/assets` to `vendor/assets`. Putting third-party assets in your `app/assets` directory is generally a mistake, and that's ok. Clean up and put them where they belong and you'll be fine.

Remove any CSS files and/or rules no longer being used. The level of detail you achieve here depends on how much time you want to spend. Removing unused CSS may be as simple as removing some files you're no longer using. If you want to dive into removing rules, there's a great tool for that called deadweight.

Remove old JavaScript files. This is usually easy and difficult. You'll probably find at least one library or plugin no longer in use. Just remove it - that's the easy part. If you have a bunch of your own custom JavaScript i.e. a Backbone application, you may need to comb through it a bit more to find out which parts are not in use.

Get rid of legacy models/database tables. A few legacy models may have leaked into your code base early on in the life of your app (when you're under rapid development). That's ok. Figure out what they are and get rid of them. Write a migration to remove the table, too.

Find any unused partials. If you're refactoring quite a bit, you might forget to remove some unused partials. Check out this gem to remove unused partials.