Categories
JavaScript Best Practices

Maintainable JavaScript — Handling Errors

Spread the love

Creating maintainable JavaScript code is important if want to keep using the code.

In this article, we’ll look at the basics of creating maintainable JavaScript code by looking at ways to handle errors.

Advantages of Throwing Errors

Throwing our own errors allow us to provide the exact text to be displayed by the browser.

We can include any information we like in addition to the line and column numbers.

The more information is given, the easier it’ll be for us to find the issue.

For instance, if we have:

function getDivs(element) {
  if (element && element.getElementsByTagName) {
    return element.getElementsByTagName("div");
  } else {
    throw new Error("divs not found");
  }
}

Then we throw an error is there’re no divs found in the element.

Knowing this makes the problem easier to find.

When to Throw Errors

Throwing errors everywhere is impractical and decrease our app’s performance.

For instance, if we have:

function addClass(element, className) {
  if (!element || typeof element.className !== "string") {
    throw new Error("element class name must be a string");
  }
  if (typeof className !== "string") {
    throw new Error("class name must be a string");
  }
  element.className += ` ${className}`;
}

then most of the function is taken up by error throwing code.

This is overkill in JavaScript.

We should only throw errors for code that’s the most likely to throw errors.

So we don’t need to throw error for the className parameter.

Instead, we write:

function addClass(element, className) {
  if (!element || typeof element.className !== "string") {
    throw new Error("element class name must be a string");
  }
  element.className += ` ${className}`;
}

element.className is most likely not to be a string, so we check for that.

Error checking isn’t necessary for known entities.

If we can’t identify the places where the function will be called ahead of time, then it’s a good idea to throw errors if something is unexpected.

JavaScript libraries should throw errors from their public interfaces for known error conditions.

This way, programmers can know where the issue is if they used it incorrectly.

The call stack should terminate in the library’s interface.

This also applies to private libraries.

Once we fixed hard to debug errors, we should throw some errors that let us identify the problem easier.

If we’re writing code that may mess up something if it does something unexpected, then we should check for those conditions and throw errors.

If the code is going to be used by someone we don’t know, then the code’s public interface should throw errors for things that are unexpected.

The try-catch Statement

JavaScript provides us with the try-catch statement to let us intercept thrown errors before they’re handled by the browser.

The code that can cause an error is in the try block and the error handling code is in the catch block.

For instance, we can write:

try {
  errorFunc();
} catch (ex) {
  handleError(ex);
}

We can also add a finally clause below the catch block.

The finally block has code that’s run regardless of whether an error occurs.

For instance, we can write:

try {
  errorFunc();
} catch (ex) {
  handleError(ex);
} finally {
  cleanUp();
}

The finally clause can be tricky.

If the try clause has a return statement, then it won’t return until finally has run.

Conclusion

We should only throw errors at the interface level and for errors that occur most often.

Also, we can use the try-catch-finally clauses to handle errors.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *