Tutorial

Error Handling in JavaScript Using try...catch

Published on August 3, 2018
author

Alligator.io

Error Handling in JavaScript Using try...catch

Good code is code that preemptively prevents errors in a program from crashing the program and instead handles those errors gracefully by doing something like recovering from the error, informing the user about it or logging the error somewhere. This is called error handling and the primary mechanism for error handling in JavaScript is the try…catch construct.

Let’s briefly go over how to use try…catch, and then also look at try…catch…finally and the throw statement to throw our own custom errors.

try…catch

Here’s the basic syntax for try…catch:

try {
  // some code that my error-out
} catch (e) {
  // this will run only if the code in the try block errors-out
}

Notice how the catch block gets access to the error object (e in the above example). The error object will have a name and a message property. In most environments the error object will also have a stack property with the stack trace leading to the error.

If you log the error object to the console, it’s name and message properties will conveniently be concatenated together.

Here’s an example where we misspell a variable name:

let myVariable = 2;
try {
  console.log(myVriable + 77);
} catch (e) {
  console.log('Oopsies -', e);
}

In this case, the catch block will be executed and the following message is printed to the console:

Oopsies - ReferenceError: myVriable is not defined

try…catch only handles errors encountered at runtime, and invalid JavaScript will error-out at parse-time so your program won’t run at all. Instead, use a linter like ESLint to catch those errors directly when authoring your code.

Throwing Custom Errors

Oftentimes instead of catching pure JavaScript errors we instead will want to catch conditions encountered in our program that should be considered errors. For this, we can make use of the throw statement to throw our own errors in a try block so that the error can be caught and dealt with:

let myVariable = prompt('Give me a number');

try {
  if (isNaN(+myVariable)) {
    // throws if the value provided can't be coerced to a number
    throw new Error('Not a number!');
  }
  console.log('Good choice', myVariable);
} catch (e) {
  console.log(e);
}

With the above example, if we don’t enter a value that can be coerced to a number we throw a custom error that’s then caught by our catch clause.

You can also see that we make use of the Error constructor to create an error object with a custom message passed-in as the first argument. In this case, our error object will have a name of Error, but we can also produce a specific error type:

try {
  if (isNaN(+myVariable)) {
    throw new TypeError('Not a number!');
  }
  console.log('Good choice', myVariable);
} catch (e) {
  console.log(e);
}

Rethrowing an error

A good coding practice is to catch and deal only errors that we expect and then to rethrow other errors to be handled by a potential parent try…catch construct:

let myVariable = prompt('Give me a number');

try {
  if (isNaN(+myVariable)) {
    throw new TypeError('Not a number!');
  }
  console.log('Good choice', myVariable);
} catch (e) {
  if (e.name === 'TypeError') {
    console.log(e);
  } else {
    throw e;
  }
}

With the above example, if an error different than our TypeError is encountered in the try clause, our catch clause rethrows the error to be dealt with using a parent try…catch construct that we would put in place.

try…catch…finally

You can also tack-on a finally block to ensure that some code runs no matter if the code in the try blocks errors-out or not:

let myVariable = 2;
try {
  console.log(myVriable + 77);
} catch (e) {
  console.log('Oopsies -', e);
} finally {
  console.log('Runs no matter what');
}

The finally block can be useful to clean-up your code.

try…finally

Like finally, the catch clause is optional and, if you want you can use try…finally to ensures that some code runs upon encountering an error.

Here for example we try to set the background color on an element that doesn’t exist. First, using a try…catch…finally:

try {
  document.querySelector('.not-there').style.backgroundColor = 'pink';
} catch (e) {
  console.log('Oh no -', e);
} finally {
  console.log('Finally runs');
}
console.log('After try block');

// Oh no - TypeError: Cannot read property 'style' of null
// Finally runs
// After try block

And now using only try…finally:

try {
  document.querySelector('.here2').style.backgroundColor = 'pink';
} finally {
  console.log('Finally runs');
}
console.log('After try block');

// Finally runs
// Uncaught TypeError: Cannot read property 'style' of null

Notice how, when the catch clause is missing, the error is uncaught and the program crashes, but only after running the code in our finally clause.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Alligator.io

author

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.