Star
0
Published Aug 04, 2016Last updated Nov 29, 2016

What to Do When Your Website is Broken

What to Do When Your Website is Broken

Our job as developers is to break and fix stuff every day. Sometimes, some of us even do it on production servers. But during emergencies, they just tend to apply a quick fix which may not actually fix anything at all— in fact, it could even make things worse.

On some days, it works! But it's still very dangerous:

broken websiteThis is a good example of fixing a bug on production with a happy ending. [source]

These things happen. But when they do, how can we address these issues with confidence and in the best way possible?

In this this article I will show you 7 general steps to fix your website, application, or code when it's broken.

1. Don't panic. Relax.

We are all humans. We make mistakes. When something gets broken, don't contribute to the mess by panicking. Try to settle down first before you do anything with it. Try drinking a glass of water and relax while trying to figure what's going on. Remember, think first before you code!

2. Reproduce the problem. Then reproduce it locally.

Let's suppose the website you're having a problem with is on production and users start complaining about a specific functionality.

Doesn't work is not enough. Ask your users to define what doesn't work means. Is there an error? What are the issue reproduction steps? Is it happening always?

Can you reproduce the bug on the production website? If yes, then try to reproduce it locally (or in your development environment). If you do this, however, you should be prepared to debug it. If you can't reproduce it locally, check out the machine-specific settings/resources. Here are few:

  • Database content: Maybe the bug appears only at a specific document that exists on production, but you don't have it locally.
  • Environment configuration: Maybe there are some environment variable or setting you need to change.
  • Make sure you're in sync with the production server code (including dependencies' versions).

But it's working on my machine!

Well, if you can't reproduce it on production, there is a high chance that it's a browser-specific issue. For example, maybe you used a function that doesn't exist on some old version of Internet Explorer, or maybe you shipped your ES2015 code directly, without transpiling it to ES5. In that case, if it's still unclear what's going on, ask for more information: Where does the issue appear? What operating system and what browser (including their versions) are they using?

If you're using the same OS and browser versions, ask them to clear the browser cache then retry. Also, you should also clear your own browser cache and retry.

Oh, yeah! Typos!

Before starting to reproduce the issue and debugging the actual code, make sure your input data is correct. You can't expect correct output if your input is incorrect (duh?).

Sometimes just by staring a bit at the code/urls/input content, you can easily fix things. As developers, we often waste lot of time debugging stuff which looks correct but turns out to be a typos in the end. And then we are like:

leo gifAfter wasting a lot of time trying to fix a typo.

So, pay attention to typos. They are funny to fix, but developers often forget to think that well, maybe it's just a typo.

3. Locate the bug. Server or client?

Today's browsers have a thing called Developer Tools. Usually you right click on the page, and then choose Inspect Element (or just Inspect) in the menu.

I have always felt more comfortable in the Chrome developer tools, but by debugging browser-specific code in other browsers, I learnt how to use the debugger on other browsers (Firefox, Safari, Internet Explorer, etc). Don't worry, they are quite similar.

Once you open the developer tools, you will see a tab called Console. Click it.

stopThis is how it looks like on facebook.com. Facebook and other popular websites add clear messages preventing humans to run JavaScript snippets copied from different sources. But we are developers! We should use this tool to debug our applications.

So, after you open the browser console, check out if there are any errors there.

For example, let's suppose we have the following snippet:

function foo () {
    undefined.baz;
}

function bar () {
    foo();
}

bar();

When executing this, obviously we will get an error. The Console will show us why:

consoleCannot read property 'baz' of undefined

By clicking on the error triangle icon, we will expand the error and see the call stack. The first link is exactly the place where the error appears. By clicking on scripts.js:2 we will open the script.js file in the developer tools and we will see that the error comes because we tried to access the baz property of undefined. A similar error would appear if we try to do null.baz.

The call stack is useful. Maybe in specific cases, the function throws an error because we're passing wrong data to it. In that case, we are not interested to fix the function (first one in the stack), but the place where we send the data.

Let's take another example. The following code has a mistake in it.

// We have a function which receives the user object
// and returns the email field
function getEmail (user) {
    return user.email;
}

// This function is asynchronous and fetches a fake user
function loadUser (cb) {
    // Do it asynchronously, simulating a database call
    setTimeout(function() {
        cb(null, {
            email: "foo@bar.com"
        });
    }, 1000);
}

// Here we want to get the email
var email = getEmail(loadUser());

Let's see how we can debug this. Just by looking at the console, we see two errors:

two errors

Always try to solve the errors in the order they appear (unless you really know that an error is appearing because of a specific reason and you're just ignore it).

In this case, the error comes from script.js:2: Cannot read property 'email' of undefined. On line two we have user.email. Since the user is a parameter sent from another function (basically from the main script) we're interested to see where it comes from. In the call stack we have that information: (anonymous function) @ script.js:14 (second line in the call stack of the first error).

On line 14, we have var email = getEmail(loadUser());. That means we send what the loadUser() call returns. Looking at the loadUser definition, we see that the function doesn't return anything. But it accepts a callback function (the cb argument)—this is currently undefined because we are not pasing it in the loadUser() call.

Instead, what we should do is:

loadUser(function (email) {
  // Do something with the email
  alert(email);
});

After applying this, the second error will be gone (since we're now passing a function).

Hopefully, you get some initial ideas on how you can inspect the client side for errors coming from the client code.

Is the error coming from the server?

If you do not have client error that's similar to the one I wrote above, maybe the problem comes from the server. In such cases, you may:

  • Get a 500 response (which will appear in the console)
  • Get the wrong data from the server which is interpreted in a wrong way on the client
  • Not get a response at all

Then, once you open the developer tools, you will see a tab called Network. Click it.

dev tools networkIt looks like this in Chrome

In the Network tab, we can see all the requests that are made.

Tip! Using the Chrome developer tools, you can disable the cache while the developer tools window is open (notice the checkbox in the top-center). Firefox has a similar checkbox.

Now, try to reproduce the bug while the developer tools window is open. After opening it, refresh the page and then follow the steps to reproduce the issue. Keep an eye on the network tab.

Are there any new requests made?

Check out for the pending and error responses (they are colored red).

In these cases, you can't solve the problem on the client side—you need to change the code that powers the server.

There are different languages for building a website but I'm going to show you a quick way to debug the Node.js code since it is a popular language for the server side (JavaScript on the server side).

4. Debugging Node.js

Many of us use the terminal (that black window where you can enter commands which are executed by the computer).

We run the Node.js scripts using node <script-name> (e.g. node app.js). Well, the key is to use a thing called debugger. This is a special statement in JavaScript. When running the code (either on client or in the Node.js debugger), it will pause the script execution on the debugger line.

There are many ways to debug code written in Node.js:

  • Using the Node.js debugger: this is the native way (doesn't require to install anything)

     node debug app.js
    
  • Using the node-inspector:

     npm install --global node-inspector
    
      node-debug app.js
    
  • Depending on your editor, you may want to debug Node.js directly in your editor.

Similarly, here are other effective ways to debug in Python, and debugging Ajax in Rails.

5. Fix the bug

Obviously, after repairing those errors, you have to make the actual changes and fix your app.

Test the functionality when you expect the issue is fixed.

test functionality

Try to reproduce the issue again. If you can reproduce the bug using an existing automated test (or if you can create one), that would be even better. When things work smoothly, you can declare the bug fixed—but don't forget to write a unit test for it (if there is no other identical one already).

6. Automated Test & Deploy

Write a test that will test the bug that you just fixed. This step ensures that when you run into this problem again in the future, you'll be better equipped to fix it.

Make sure the tests are passing and actual === expected.

gameactual !== expected

Now you can ship the changes!

7. One last thing...

Fixing bugs on production can be dangerous. Don't do it unless you're really sure that's what you want.

Conclusion

Hopefully, these steps helped you get a better idea of the things you need do when your application or website is broken. Don't forget that each bug is unique and there is no generic cure for all of them yet.

Happy Debugging & Fixing!

Node.js Tutorial: Building a Simple CMS with Dynamic User Content with Prismic.io
Tutorial: Build your own Smart TV Using RaspberryPi, NodeJS and Socket.io
Node.js Async Tutorial: Building a Mass Mailer
Star
0