Exception Handling in JavaScript

If you work with JavaScript, you know that errors are unavoidable—how you handle them determines whether they work for or against you. This article discusses best practices for handling errors in JavaScript.

In JavaScript, errors are only detected during runtime. Therefore, it is impossible to get compile-time errors when building JavaScript applications.

There are several reasons errors may occur: invalid input, server error, or errors, even in the application code.

In this article, we will discuss how errors are handled in JavaScript, so that when errors occur, they won't crash the application. We can do this using exception handling in JavaScript.

Exception handling allows us to write custom behavior for different errors caused by application users, the server, and many other causes of these errors.

What Is Exception Handling?

Applications occasionally run into errors. Operations such as dividing a non-zero number by zero, and failing to read a file would give an exception in our code.

Error handling is the procedure/method used to handle the abnormal behavior of our application. It is the method used to handle the possibility of failure in applications.

With the help of exception handling, we can handle abnormal conditions or crashes and help the user take necessary actions with a proper exception-handling message.

Why Is Exception Handling Needed?

When application codes generate errors and raise exceptions, it doesn’t make sense to continue with the remaining code. Instead, we try to recover from the error with the use of exception handling.

Without proper handling methods, errors may crash the application and prevent its goal from being achieved.

Noticing and handling errors or possible failures of an application saves associated programs from further outages or crashes.

If an unexpected response is given and then processed, the user gets incorrect information and a bad impression of the application.

A well-written application should have a good exception handling mechanism and approach to various kinds of errors that are likely to happen within the application during usage.

With exception handling, we can manage these problems and prevent the application from crashing. By using exception handling, we can control the flow of an application.

How to Handle Exceptions in JavaScript

There are many ways to handle exceptions in JavaScript. JavaScript provides a mechanism to handle errors using the try-catch-finally block, similar to languages like Java or C#.

The mechanism can be used in the following ways:

  • throw statements
  • try-catch
  • try-catch-finally

Try Blocks

Executable codes that are likely to raise exceptions or cause errors are placed in the try block.

While the code in the try block executes, when an error is detected, it passes the error to the catch block, and the necessary actions are taken in the catch block. If the necessary actions are not taken by the catch block, the application starts to behave abnormally, and a crash is likely to occur.

Catch Blocks

The code that should be executed when errors occur in the try block is written in the catch block. The error handling code is usually written in the catch block.

The catch block can contain either the user-defined exception handler or the built-in error handler in JavaScript.

Note that the catch block only executes when there is an error from the try block. There can also be more than one catch block to handle multiple exceptions.

Finally Blocks

The finally block will execute regardless of whether there is an error from the try block.

Try-Catch Statements

Try-catch statements are not only common in JavaScript but also widely used in other programming languages. They are used to handle exceptions that arise in the code.

JavaScript uses try-catch statements to trap runtime errors and handle them properly.

Try blocks contain code that might throw errors, and catch blocks contain code to handle such errors. When a try block encounters errors, the catch block is triggered. Otherwise, execution continues after each try-catch statement. Here is an example:

  try {
    thisfunctiondoesnotexit()
  }


  catch(e) {
    console.log(e);
  }

In the code above, we attempt to use a function that does not exist in the application. The try block throws an error to the catch block, which logs it to the console.

JavaScript Try-Catch-Finally Statements

A try-catch statement can also be written with an added finally block. The code in the finally block executes, regardless of whether an error occurs in the try statement.

The following is an example of how try-catch-finally is being implemented to handle errors in JavaScript:

  try {
    thisfunctiondoesnotexit();
  }
  catch(e) {
    console.log(e);
  }
  finally {
    console.log("Code executed successfully");
  }

In this example, the finally block will run regardless of whether the try block throws an error. This is the simple syntax of how to handle errors in JavaScript.

However, errors can be much more complicated and handled more professionally. Using throw statements allows for custom errors to be thrown into the catch block, which is handled based on the code in the catch block.

Let's take a look at some more complicated JavaScript error handling examples. We will create a simple calculator that accepts user input in JavaScript and make use of exception handling and promises. Run the JavaScript code below in your browser, and let's understand how it works.

  const throwExceptions = () => {
    let result
    let first = prompt('Enter first number: ')
    let second = prompt('Enter second number: ')
    try {

      if (first == '' || second == '') throw 'Number cannot be empty'

      result = first / second

    } catch (err) {
        console.log(err)
    } finally {
        console.log(`The division of ${first} & ${second} is ${result}`)
    }
  }
  throwExceptions()

Here, we have created a function that handles errors generated from our code.

In the above code, we prompt the user to input two numbers. These two numbers will then be divided by each other, with the first number being the numerator and the second being the denominator.

Then we use the JavaScript if and throw statement to test whether the input given by the user is valid (i.e., whether it is empty).

In our code, we throw a custom error using the throw statement. We can also do some other checks on the user input to check for validity and send the errors to the catch block if there are any.

The catch block catches errors and displays the message defined in throw statements.

This allows for control and better flow handling of the application by the developer and also helps the user to know what went wrong and why the application does not give the expected result.

The finally block executes regardless of whether an error is thrown and is used to display the result of the operation, even when there is an error.

In addition to errors defined by the throw statement, other errors can also be caught and displayed in the catch block. The throw statement only allows for flexibility and custom error definition.

Using the try-catch-finally statement in JavaScript is a good example of how to handle exceptions and errors. However, there is more.

Handling Errors with JavaScript Promises

We can also catch errors using JavaScript promises. We will build the same program using JavaScript promises. Run the code below in your browser, and let's take a closer look.

  const throwExceptions = (first, second) => {
    return promise = new Promise((resolve, reject) => {
      if (first == '' || second == '') reject ('Number cannot be empty')

      resolve(first / second)
    })
  }

  let first = prompt('Enter first number: ')
  let second = prompt('Enter second number: ')

  throwExceptions(first, second)
    .then(result => console.log(result))

The code above has helped us to handle our simple calculator app using JavaScript promises. The way the application works does not differ from the previous one. Only the implementation differs. We have only used promises to more effectively handle our errors.

Promises are the ideal way to handle errors in asynchronous code. They provide better ways to handle asynchronous operations than callbacks and events.

We created and returned a new promise object in our function: throwExceptions. Our new promise tests for the input and rejects it if it is invalid.

The operation will be processed, and the result will be displayed if the input is valid.

This is how JavaScript promises work. However, we can do more checking and get more detailed information about errors when they occur. To accomplish this, we can use the Honeybadger error-monitoring tool.

Let's get a better understanding how to use this tool.

How to Handle Exceptions with Honeybadger

Honeybadger provides developers with tools to manage and fix errors. It offers one of the best error-monitoring tools to track and monitor errors from your code.

With the Honeybadger error-monitoring tool, developers and businesses can track and manage application errors and make their users happy.

I’ll work you through the steps you need to get started with Honeybadger and how to monitor errors in your application with Honeybadger.

Follow the steps below to get Honeybadger configured and set up on your Nodejs application.

Yes, we will be testing the Honeybadger library with a Node application.

In this application, we will try to access a function that does not exist. This will raise an error. We will then use Honeybadger to monitor and get more detailed information about this error.

Step 1

Start by creating a Node project. Create a folder and give it a name that suits you.

mkdir test-app
cd test-app

Step 2

In this application, we will only make use of two libraries: Express and Honeybadger. Run the following command to install these two libraries in your project.

  npm install express

  npm install @honeybadger-io/js --save

Step 3

Create an index.js file and put in the following code:

  const express = require('express');

  const app = express();

  // Website routing
  app.get('/', (req, res) => {
    res.send("index");
  });

  app.listen(port, () => {
    console.log('Server is running');
  });

This program will not run because we have tried to access a variable that does not exist in the application. Let’s see how Honeybadger helps us monitor for this error.

Step 4

Sign up on the Honeybadger website and click on ‘start free trial’, as shown in the following image.

Honeybadger.io

Step 5

Click on ‘add project’ and give your project a name. Then select Nodejs as the language, and create a project.

How to create project on Honeybadger

Step 6

The next page displays a configuration key you can use to track errors in your code. Update your code with the following.

  const express = require('express');
  const Honeybadger = require('@honeybadger-io/js')

  Honeybadger.configure({
    apiKey: 'hbp_aRzcPWosdNhgU01ETnv25YF2OFF0nD3MiWJj'
  })

  const app = express();

  // Website routing
  app.get('/', (req, res) => {
    try {
      thisfunctiondoesnotexit()
    } catch(e) {
      Honeybadger.notify(e);
    }
    res.send("index");
  });

  app.listen(3000, () => {
    console.log(`App Listening at 3000`);
  });

In the program above, we try to access a function that does not exist. This code produces an error when it runs. Let’s take a look at how Honeybadger helps us manage this error from our Honeybadger account.

Navigate to your Honeybadger account and open up the project we created earlier. Click on the error tab and see which error is displayed.

Honeybadger error page

If you have successfully configured your application with Honeybadger, you should get a screen that looks like this.

This screen displays a ReferenceError in your code.

To get more information about this error, click on the error. This will display more detailed information about the error in your application code, as shown in the following image:

Honeybadger error details

This page displays all relevant information about the error in your code, such as the error message, at what line the error occurred, and other relevant details.

Honeybadger is a great tool for developers who are willing to satisfy their customers and minimize errors and bugs in their applications.

Try out the simple calculator we have built in this article and see how Honeybadger helps you track these errors conveniently.

Conclusion

We learned how to handle errors in JavaScript in this article. When writing JavaScript codes, errors are quite common.

Errors in application code can be tedious to find and can be expensive when they occur and crash the application. Honeybadger offers monitoring tools that help detect errors faster and easier.

What to do next:
  1. Try Honeybadger for FREE
    Honeybadger helps you find and fix errors before your users can even report them. Get set up in minutes and check monitoring off your to-do list.
    Start free trial
    Easy 5-minute setup — No credit card required
  2. Get the Honeybadger newsletter
    Each month we share news, best practices, and stories from the DevOps & monitoring community—exclusively for developers like you.
    author photo

    Salem Olorundare

    Salem is a software engineer who specializes in JavaScript. He enjoys breaking down advanced technical topics in his writing so they can be understood by people of all skill levels.

    More articles by Salem Olorundare
    Stop wasting time manually checking logs for errors!

    Try the only application health monitoring tool that allows you to track application errors, uptime, and cron jobs in one simple platform.

    • Know when critical errors occur, and which customers are affected.
    • Respond instantly when your systems go down.
    • Improve the health of your systems over time.
    • Fix problems before your customers can report them!

    As developers ourselves, we hated wasting time tracking down errors—so we built the system we always wanted.

    Honeybadger tracks everything you need and nothing you don't, creating one simple solution to keep your application running and error free so you can do what you do best—release new code. Try it free and see for yourself.

    Start free trial
    Simple 5-minute setup — No credit card required

    Learn more

    "We've looked at a lot of error management systems. Honeybadger is head and shoulders above the rest and somehow gets better with every new release."
    — Michael Smith, Cofounder & CTO of YvesBlue

    Honeybadger is trusted by top companies like:

    “Everyone is in love with Honeybadger ... the UI is spot on.”
    Molly Struve, Sr. Site Reliability Engineer, Netflix
    Start free trial
    Are you using Sentry, Rollbar, Bugsnag, or Airbrake for your monitoring? Honeybadger includes error tracking with a whole suite of amazing monitoring tools — all for probably less than you're paying now. Discover why so many companies are switching to Honeybadger here.
    Start free trial
    Stop digging through chat logs to find the bug-fix someone mentioned last month. Honeybadger's built-in issue tracker keeps discussion central to each error, so that if it pops up again you'll be able to pick up right where you left off.
    Start free trial
    “Wow — Customers are blown away that I email them so quickly after an error.”
    Chris Patton, Founder of Punchpass.com
    Start free trial